From bfb3e5dd8dfd84dfd13649393abab63e43267b00 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:03 +0100 Subject: [PATCH 01/17] tipc: move and rename the legacy nl api to "nl compat" The new netlink API is no longer "v2" but rather the standard API and the legacy API is now "nl compat". We split them into separate start/stop and put them in different files in order to further distinguish them. Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/Makefile | 4 +- net/tipc/bcast.c | 2 +- net/tipc/bearer.c | 4 +- net/tipc/core.c | 7 +++ net/tipc/core.h | 1 - net/tipc/link.c | 2 +- net/tipc/name_table.c | 2 +- net/tipc/net.c | 2 +- net/tipc/netlink.c | 67 ++---------------------- net/tipc/netlink.h | 4 +- net/tipc/netlink_compat.c | 105 ++++++++++++++++++++++++++++++++++++++ net/tipc/node.c | 2 +- net/tipc/socket.c | 4 +- 13 files changed, 130 insertions(+), 76 deletions(-) create mode 100644 net/tipc/netlink_compat.c diff --git a/net/tipc/Makefile b/net/tipc/Makefile index 333e4592772c..69b82bbc60d3 100644 --- a/net/tipc/Makefile +++ b/net/tipc/Makefile @@ -7,8 +7,8 @@ obj-$(CONFIG_TIPC) := tipc.o tipc-y += addr.o bcast.o bearer.o config.o \ core.o link.o discover.o msg.o \ name_distr.o subscr.o name_table.o net.o \ - netlink.o node.o socket.o log.o eth_media.o \ - server.o + netlink.o netlink_compat.o node.o socket.o log.o eth_media.o \ + server.o socket.o tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o tipc-$(CONFIG_SYSCTL) += sysctl.o diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 81b1fef1f5e0..e96fd6a6d5c2 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) tipc_bclink_lock(net); - hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, + hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, NLM_F_MULTI, TIPC_NL_LINK_GET); if (!hdr) return -EMSGSIZE; diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 33dc3486d16c..35d400e8c2e5 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -658,7 +658,7 @@ static int __tipc_nl_add_bearer(struct tipc_nl_msg *msg, struct nlattr *attrs; struct nlattr *prop; - hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, + hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, NLM_F_MULTI, TIPC_NL_BEARER_GET); if (!hdr) return -EMSGSIZE; @@ -924,7 +924,7 @@ static int __tipc_nl_add_media(struct tipc_nl_msg *msg, struct nlattr *attrs; struct nlattr *prop; - hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, + hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, NLM_F_MULTI, TIPC_NL_MEDIA_GET); if (!hdr) return -EMSGSIZE; diff --git a/net/tipc/core.c b/net/tipc/core.c index 674bd2698528..2d06d1f8b6e6 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c @@ -111,6 +111,10 @@ static int __init tipc_init(void) if (err) goto out_netlink; + err = tipc_netlink_compat_start(); + if (err) + goto out_netlink_compat; + err = tipc_socket_init(); if (err) goto out_socket; @@ -136,6 +140,8 @@ out_pernet: out_sysctl: tipc_socket_stop(); out_socket: + tipc_netlink_compat_stop(); +out_netlink_compat: tipc_netlink_stop(); out_netlink: pr_err("Unable to start in single node mode\n"); @@ -146,6 +152,7 @@ static void __exit tipc_exit(void) { tipc_bearer_cleanup(); tipc_netlink_stop(); + tipc_netlink_compat_stop(); tipc_socket_stop(); tipc_unregister_sysctl(); unregister_pernet_subsys(&tipc_net_ops); diff --git a/net/tipc/core.h b/net/tipc/core.h index 817b2e9d4227..451c346fd3cf 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h @@ -115,5 +115,4 @@ void tipc_unregister_sysctl(void); #define tipc_register_sysctl() 0 #define tipc_unregister_sysctl() #endif - #endif diff --git a/net/tipc/link.c b/net/tipc/link.c index 942491234099..466f28fcf215 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -2498,7 +2498,7 @@ static int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg, struct nlattr *prop; struct tipc_net *tn = net_generic(net, tipc_net_id); - hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, + hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, NLM_F_MULTI, TIPC_NL_LINK_GET); if (!hdr) return -EMSGSIZE; diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 18a3d44238bc..2251912264a2 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -1055,7 +1055,7 @@ static int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg, *last_publ = p->key; hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, - &tipc_genl_v2_family, NLM_F_MULTI, + &tipc_genl_family, NLM_F_MULTI, TIPC_NL_NAME_TABLE_GET); if (!hdr) return -EMSGSIZE; diff --git a/net/tipc/net.c b/net/tipc/net.c index 263267e0e7fe..8b0fb0966628 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c @@ -156,7 +156,7 @@ static int __tipc_nl_add_net(struct net *net, struct tipc_nl_msg *msg) void *hdr; struct nlattr *attrs; - hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, + hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, NLM_F_MULTI, TIPC_NL_NET_GET); if (!hdr) return -EMSGSIZE; 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 @@ */ #include "core.h" -#include "config.h" #include "socket.h" #include "name_table.h" #include "bearer.h" @@ -44,39 +43,6 @@ #include "net.h" #include -static int handle_cmd(struct sk_buff *skb, struct genl_info *info) -{ - struct net *net = genl_info_net(info); - struct sk_buff *rep_buf; - struct nlmsghdr *rep_nlh; - struct nlmsghdr *req_nlh = info->nlhdr; - struct tipc_genlmsghdr *req_userhdr = info->userhdr; - int hdr_space = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN); - u16 cmd; - - if ((req_userhdr->cmd & 0xC000) && - (!netlink_net_capable(skb, CAP_NET_ADMIN))) - cmd = TIPC_CMD_NOT_NET_ADMIN; - else - cmd = req_userhdr->cmd; - - rep_buf = tipc_cfg_do_cmd(net, req_userhdr->dest, cmd, - nlmsg_data(req_nlh) + GENL_HDRLEN + - TIPC_GENL_HDRLEN, - nlmsg_attrlen(req_nlh, GENL_HDRLEN + - TIPC_GENL_HDRLEN), hdr_space); - - if (rep_buf) { - skb_push(rep_buf, hdr_space); - rep_nlh = nlmsg_hdr(rep_buf); - memcpy(rep_nlh, req_nlh, hdr_space); - rep_nlh->nlmsg_len = rep_buf->len; - genlmsg_unicast(net, rep_buf, NETLINK_CB(skb).portid); - } - - return 0; -} - static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { [TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, }, [TIPC_NLA_BEARER] = { .type = NLA_NESTED, }, @@ -89,28 +55,10 @@ static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { [TIPC_NLA_NAME_TABLE] = { .type = NLA_NESTED, } }; -/* Legacy ASCII API */ -static struct genl_family tipc_genl_family = { - .id = GENL_ID_GENERATE, - .name = TIPC_GENL_NAME, - .version = TIPC_GENL_VERSION, - .hdrsize = TIPC_GENL_HDRLEN, - .maxattr = 0, - .netnsok = true, -}; - -/* Legacy ASCII API */ -static struct genl_ops tipc_genl_ops[] = { - { - .cmd = TIPC_GENL_CMD, - .doit = handle_cmd, - }, -}; - /* Users of the legacy API (tipc-config) can't handle that we add operations, * so we have a separate genl handling for the new API. */ -struct genl_family tipc_genl_v2_family = { +struct genl_family tipc_genl_family = { .id = GENL_ID_GENERATE, .name = TIPC_GENL_V2_NAME, .version = TIPC_GENL_V2_VERSION, @@ -202,9 +150,9 @@ static const struct genl_ops tipc_genl_v2_ops[] = { int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr) { - u32 maxattr = tipc_genl_v2_family.maxattr; + u32 maxattr = tipc_genl_family.maxattr; - *attr = tipc_genl_v2_family.attrbuf; + *attr = tipc_genl_family.attrbuf; if (!*attr) return -EOPNOTSUPP; @@ -215,13 +163,7 @@ int tipc_netlink_start(void) { int res; - res = genl_register_family_with_ops(&tipc_genl_family, tipc_genl_ops); - if (res) { - pr_err("Failed to register legacy interface\n"); - return res; - } - - res = genl_register_family_with_ops(&tipc_genl_v2_family, + res = genl_register_family_with_ops(&tipc_genl_family, tipc_genl_v2_ops); if (res) { pr_err("Failed to register netlink interface\n"); @@ -233,5 +175,4 @@ int tipc_netlink_start(void) void tipc_netlink_stop(void) { genl_unregister_family(&tipc_genl_family); - genl_unregister_family(&tipc_genl_v2_family); } 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 @@ #ifndef _TIPC_NETLINK_H #define _TIPC_NETLINK_H -extern struct genl_family tipc_genl_v2_family; +extern struct genl_family tipc_genl_family; int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***buf); struct tipc_nl_msg { @@ -46,6 +46,8 @@ struct tipc_nl_msg { }; int tipc_netlink_start(void); +int tipc_netlink_compat_start(void); void tipc_netlink_stop(void); +void tipc_netlink_compat_stop(void); #endif diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c new file mode 100644 index 000000000000..f752854c8b10 --- /dev/null +++ b/net/tipc/netlink_compat.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2014, Ericsson AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "core.h" +#include "config.h" +#include +#include + +static int handle_cmd(struct sk_buff *skb, struct genl_info *info) +{ + struct net *net = genl_info_net(info); + struct sk_buff *rep_buf; + struct nlmsghdr *rep_nlh; + struct nlmsghdr *req_nlh = info->nlhdr; + struct tipc_genlmsghdr *req_userhdr = info->userhdr; + int hdr_space = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN); + u16 cmd; + + if ((req_userhdr->cmd & 0xC000) && + (!netlink_net_capable(skb, CAP_NET_ADMIN))) + cmd = TIPC_CMD_NOT_NET_ADMIN; + else + cmd = req_userhdr->cmd; + + rep_buf = tipc_cfg_do_cmd(net, req_userhdr->dest, cmd, + nlmsg_data(req_nlh) + GENL_HDRLEN + + TIPC_GENL_HDRLEN, + nlmsg_attrlen(req_nlh, GENL_HDRLEN + + TIPC_GENL_HDRLEN), hdr_space); + + if (rep_buf) { + skb_push(rep_buf, hdr_space); + rep_nlh = nlmsg_hdr(rep_buf); + memcpy(rep_nlh, req_nlh, hdr_space); + rep_nlh->nlmsg_len = rep_buf->len; + genlmsg_unicast(net, rep_buf, NETLINK_CB(skb).portid); + } + + return 0; +} + +static struct genl_family tipc_genl_compat_family = { + .id = GENL_ID_GENERATE, + .name = TIPC_GENL_NAME, + .version = TIPC_GENL_VERSION, + .hdrsize = TIPC_GENL_HDRLEN, + .maxattr = 0, + .netnsok = true, +}; + +static struct genl_ops tipc_genl_compat_ops[] = { + { + .cmd = TIPC_GENL_CMD, + .doit = handle_cmd, + }, +}; + +int tipc_netlink_compat_start(void) +{ + int res; + + res = genl_register_family_with_ops(&tipc_genl_compat_family, + tipc_genl_compat_ops); + if (res) { + pr_err("Failed to register legacy compat interface\n"); + return res; + } + + return 0; +} + +void tipc_netlink_compat_stop(void) +{ + genl_unregister_family(&tipc_genl_compat_family); +} diff --git a/net/tipc/node.c b/net/tipc/node.c index 52308498f208..995618d6da9d 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -623,7 +623,7 @@ static int __tipc_nl_add_node(struct tipc_nl_msg *msg, struct tipc_node *node) void *hdr; struct nlattr *attrs; - hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, + hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, NLM_F_MULTI, TIPC_NL_NODE_GET); if (!hdr) return -EMSGSIZE; diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 4a98d15a1323..d76c171f7b7e 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -2783,7 +2783,7 @@ static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb, struct tipc_net *tn = net_generic(net, tipc_net_id); hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, - &tipc_genl_v2_family, NLM_F_MULTI, TIPC_NL_SOCK_GET); + &tipc_genl_family, NLM_F_MULTI, TIPC_NL_SOCK_GET); if (!hdr) goto msg_cancel; @@ -2864,7 +2864,7 @@ static int __tipc_nl_add_sk_publ(struct sk_buff *skb, struct nlattr *attrs; hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, - &tipc_genl_v2_family, NLM_F_MULTI, TIPC_NL_PUBL_GET); + &tipc_genl_family, NLM_F_MULTI, TIPC_NL_PUBL_GET); if (!hdr) goto msg_cancel; From d0796d1ef63deb38147729664691ba3090930b26 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:04 +0100 Subject: [PATCH 02/17] tipc: convert legacy nl bearer dump to nl compat Introduce a framework for dumping netlink data from the new netlink API and formatting it to the old legacy API format. This is done by looping the dump data and calling a format handler for each entity, in this case a bearer. We dump until either all data is dumped or we reach the limited buffer size of the legacy API. Remember, the legacy API doesn't scale. In this commit we convert TIPC_CMD_GET_BEARER_NAMES to use the compat layer. Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- include/uapi/linux/tipc_config.h | 5 + net/tipc/bearer.c | 29 ---- net/tipc/bearer.h | 1 - net/tipc/config.c | 3 - net/tipc/netlink_compat.c | 274 ++++++++++++++++++++++++++++++- 5 files changed, 278 insertions(+), 34 deletions(-) diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h index 876d0a14863c..e1f4f05f4c5c 100644 --- a/include/uapi/linux/tipc_config.h +++ b/include/uapi/linux/tipc_config.h @@ -272,6 +272,11 @@ static inline int TLV_CHECK(const void *tlv, __u16 space, __u16 exp_type) (ntohs(((struct tlv_desc *)tlv)->tlv_type) == exp_type); } +static inline int TLV_GET_LEN(struct tlv_desc *tlv) +{ + return ntohs(tlv->tlv_len); +} + static inline int TLV_SET(void *tlv, __u16 type, void *data, __u16 len) { struct tlv_desc *tlv_ptr; diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 35d400e8c2e5..7a9e29641e61 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -205,35 +205,6 @@ struct tipc_bearer *tipc_bearer_find(struct net *net, const char *name) return NULL; } -/** - * tipc_bearer_get_names - record names of bearers in buffer - */ -struct sk_buff *tipc_bearer_get_names(struct net *net) -{ - struct tipc_net *tn = net_generic(net, tipc_net_id); - struct sk_buff *buf; - struct tipc_bearer *b; - int i, j; - - buf = tipc_cfg_reply_alloc(MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME)); - if (!buf) - return NULL; - - for (i = 0; media_info_array[i] != NULL; i++) { - for (j = 0; j < MAX_BEARERS; j++) { - b = rtnl_dereference(tn->bearer_list[j]); - if (!b) - continue; - if (b->media == media_info_array[i]) { - tipc_cfg_append_tlv(buf, TIPC_TLV_BEARER_NAME, - b->name, - strlen(b->name) + 1); - } - } - } - return buf; -} - void tipc_bearer_add_dest(struct net *net, u32 bearer_id, u32 dest) { struct tipc_net *tn = net_generic(net, tipc_net_id); diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index c035e3e24764..956858276d93 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -205,7 +205,6 @@ void tipc_disable_l2_media(struct tipc_bearer *b); int tipc_l2_send_msg(struct net *net, struct sk_buff *buf, struct tipc_bearer *b, struct tipc_media_addr *dest); -struct sk_buff *tipc_bearer_get_names(struct net *net); void tipc_bearer_add_dest(struct net *net, u32 bearer_id, u32 dest); void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest); struct tipc_bearer *tipc_bearer_find(struct net *net, const char *name); diff --git a/net/tipc/config.c b/net/tipc/config.c index 6873360cda53..52e84b0ac48a 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -252,9 +252,6 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, rep_tlv_buf = tipc_nametbl_get(net, req_tlv_area, req_tlv_space); break; - case TIPC_CMD_GET_BEARER_NAMES: - rep_tlv_buf = tipc_bearer_get_names(net); - break; case TIPC_CMD_GET_MEDIA_NAMES: rep_tlv_buf = tipc_media_get_names(); break; diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index f752854c8b10..bd75ea290e3a 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -33,9 +33,265 @@ #include "core.h" #include "config.h" +#include "bearer.h" #include #include +/* The legacy API had an artificial message length limit called + * ULTRA_STRING_MAX_LEN. + */ +#define ULTRA_STRING_MAX_LEN 32768 + +#define TIPC_SKB_MAX TLV_SPACE(ULTRA_STRING_MAX_LEN) + +#define REPLY_TRUNCATED "\n" + +struct tipc_nl_compat_msg { + u16 cmd; + int rep_size; + struct sk_buff *rep; + struct tlv_desc *req; + struct sock *dst_sk; +}; + +struct tipc_nl_compat_cmd_dump { + int (*dumpit)(struct sk_buff *, struct netlink_callback *); + int (*format)(struct tipc_nl_compat_msg *msg, struct nlattr **attrs); +}; + +static int tipc_skb_tailroom(struct sk_buff *skb) +{ + int tailroom; + int limit; + + tailroom = skb_tailroom(skb); + limit = TIPC_SKB_MAX - skb->len; + + if (tailroom < limit) + return tailroom; + + return limit; +} + +static int tipc_add_tlv(struct sk_buff *skb, u16 type, void *data, u16 len) +{ + struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(skb); + + if (tipc_skb_tailroom(skb) < TLV_SPACE(len)) + return -EMSGSIZE; + + skb_put(skb, TLV_SPACE(len)); + tlv->tlv_type = htons(type); + tlv->tlv_len = htons(TLV_LENGTH(len)); + if (len && data) + memcpy(TLV_DATA(tlv), data, len); + + return 0; +} + +static struct sk_buff *tipc_tlv_alloc(int size) +{ + int hdr_len; + struct sk_buff *buf; + + size = TLV_SPACE(size); + hdr_len = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN); + + buf = alloc_skb(hdr_len + size, GFP_KERNEL); + if (!buf) + return NULL; + + skb_reserve(buf, hdr_len); + + return buf; +} + +static struct sk_buff *tipc_get_err_tlv(char *str) +{ + int str_len = strlen(str) + 1; + struct sk_buff *buf; + + buf = tipc_tlv_alloc(TLV_SPACE(str_len)); + if (buf) + tipc_add_tlv(buf, TIPC_TLV_ERROR_STRING, str, str_len); + + return buf; +} + +static int __tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, + struct tipc_nl_compat_msg *msg, + struct sk_buff *arg) +{ + int len = 0; + int err; + struct sk_buff *buf; + struct nlmsghdr *nlmsg; + struct netlink_callback cb; + + memset(&cb, 0, sizeof(cb)); + cb.nlh = (struct nlmsghdr *)arg->data; + cb.skb = arg; + + buf = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + buf->sk = msg->dst_sk; + + do { + int rem; + + len = (*cmd->dumpit)(buf, &cb); + + nlmsg_for_each_msg(nlmsg, nlmsg_hdr(buf), len, rem) { + struct nlattr **attrs; + + err = tipc_nlmsg_parse(nlmsg, &attrs); + if (err) + goto err_out; + + err = (*cmd->format)(msg, attrs); + if (err) + goto err_out; + + if (tipc_skb_tailroom(msg->rep) <= 1) { + err = -EMSGSIZE; + goto err_out; + } + } + + skb_reset_tail_pointer(buf); + buf->len = 0; + + } while (len); + + err = 0; + +err_out: + kfree_skb(buf); + + if (err == -EMSGSIZE) { + /* The legacy API only considered messages filling + * "ULTRA_STRING_MAX_LEN" to be truncated. + */ + if ((TIPC_SKB_MAX - msg->rep->len) <= 1) { + char *tail = skb_tail_pointer(msg->rep); + + if (*tail != '\0') + sprintf(tail - sizeof(REPLY_TRUNCATED) - 1, + REPLY_TRUNCATED); + } + + return 0; + } + + return err; +} + +static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, + struct tipc_nl_compat_msg *msg) +{ + int err; + struct sk_buff *arg; + + msg->rep = tipc_tlv_alloc(msg->rep_size); + if (!msg->rep) + return -ENOMEM; + + arg = nlmsg_new(0, GFP_KERNEL); + if (!arg) { + kfree_skb(msg->rep); + return -ENOMEM; + } + + err = __tipc_nl_compat_dumpit(cmd, msg, arg); + if (err) + kfree_skb(msg->rep); + + kfree_skb(arg); + + return err; +} + +static int tipc_nl_compat_bearer_dump(struct tipc_nl_compat_msg *msg, + struct nlattr **attrs) +{ + struct nlattr *bearer[TIPC_NLA_BEARER_MAX + 1]; + + nla_parse_nested(bearer, TIPC_NLA_BEARER_MAX, attrs[TIPC_NLA_BEARER], + NULL); + + return tipc_add_tlv(msg->rep, TIPC_TLV_BEARER_NAME, + nla_data(bearer[TIPC_NLA_BEARER_NAME]), + nla_len(bearer[TIPC_NLA_BEARER_NAME])); +} + +static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) +{ + struct tipc_nl_compat_cmd_dump dump; + + memset(&dump, 0, sizeof(dump)); + + switch (msg->cmd) { + case TIPC_CMD_GET_BEARER_NAMES: + msg->rep_size = MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME); + dump.dumpit = tipc_nl_bearer_dump; + dump.format = tipc_nl_compat_bearer_dump; + return tipc_nl_compat_dumpit(&dump, msg); + } + + return -EOPNOTSUPP; +} + +static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info) +{ + int err; + int len; + struct tipc_nl_compat_msg msg; + struct nlmsghdr *req_nlh; + struct nlmsghdr *rep_nlh; + struct tipc_genlmsghdr *req_userhdr = info->userhdr; + struct net *net = genl_info_net(info); + + memset(&msg, 0, sizeof(msg)); + + req_nlh = (struct nlmsghdr *)skb->data; + msg.req = nlmsg_data(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN; + msg.cmd = req_userhdr->cmd; + msg.dst_sk = info->dst_sk; + + if ((msg.cmd & 0xC000) && (!netlink_net_capable(skb, CAP_NET_ADMIN))) { + msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_NET_ADMIN); + err = -EACCES; + goto send; + } + + len = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN); + if (TLV_GET_LEN(msg.req) && !TLV_OK(msg.req, len)) { + msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED); + err = -EOPNOTSUPP; + goto send; + } + + err = tipc_nl_compat_handle(&msg); + if (err == -EOPNOTSUPP) + msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED); + else if (err == -EINVAL) + msg.rep = tipc_get_err_tlv(TIPC_CFG_TLV_ERROR); +send: + if (!msg.rep) + return err; + + len = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN); + skb_push(msg.rep, len); + rep_nlh = nlmsg_hdr(msg.rep); + memcpy(rep_nlh, info->nlhdr, len); + rep_nlh->nlmsg_len = msg.rep->len; + genlmsg_unicast(net, msg.rep, NETLINK_CB(skb).portid); + + return err; +} + static int handle_cmd(struct sk_buff *skb, struct genl_info *info) { struct net *net = genl_info_net(info); @@ -69,6 +325,22 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info) return 0; } +/* Temporary function to keep functionality throughout the patchset + * without having to mess with the global variables and other trickery + * of the old API. + */ +static int tipc_nl_compat_tmp_wrap(struct sk_buff *skb, struct genl_info *info) +{ + struct tipc_genlmsghdr *req = info->userhdr; + + switch (req->cmd) { + case TIPC_CMD_GET_BEARER_NAMES: + return tipc_nl_compat_recv(skb, info); + } + + return handle_cmd(skb, info); +} + static struct genl_family tipc_genl_compat_family = { .id = GENL_ID_GENERATE, .name = TIPC_GENL_NAME, @@ -81,7 +353,7 @@ static struct genl_family tipc_genl_compat_family = { static struct genl_ops tipc_genl_compat_ops[] = { { .cmd = TIPC_GENL_CMD, - .doit = handle_cmd, + .doit = tipc_nl_compat_tmp_wrap, }, }; From 9ab154658a7ff2c5076607e02f18581c6859fc2a Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:05 +0100 Subject: [PATCH 03/17] tipc: convert legacy nl bearer enable/disable to nl compat Introduce a framework for transcoding legacy nl action into actions (.doit) calls from the new nl API. This is done by converting the incoming TLV data into netlink data with nested netlink attributes. Unfortunately due to the randomness of the legacy API we can't do this generically so each legacy netlink command requires a specific transcoding recipe. In this case for bearer enable and bearer disable. Convert TIPC_CMD_ENABLE_BEARER and TIPC_CMD_DISABLE_BEARER into doit compat calls. Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- include/uapi/linux/tipc_config.h | 5 ++ net/tipc/bearer.c | 26 ++---- net/tipc/bearer.h | 3 - net/tipc/config.c | 33 ------- net/tipc/netlink_compat.c | 144 +++++++++++++++++++++++++++++++ 5 files changed, 154 insertions(+), 57 deletions(-) diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h index e1f4f05f4c5c..f9226566c1b8 100644 --- a/include/uapi/linux/tipc_config.h +++ b/include/uapi/linux/tipc_config.h @@ -277,6 +277,11 @@ static inline int TLV_GET_LEN(struct tlv_desc *tlv) return ntohs(tlv->tlv_len); } +static inline int TLV_CHECK_TYPE(struct tlv_desc *tlv, __u16 type) +{ + return (ntohs(tlv->tlv_type) == type); +} + static inline int TLV_SET(void *tlv, __u16 type, void *data, __u16 len) { struct tlv_desc *tlv_ptr; diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 7a9e29641e61..de1c800ef806 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -236,8 +236,8 @@ void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest) /** * tipc_enable_bearer - enable bearer with the given name */ -int tipc_enable_bearer(struct net *net, const char *name, u32 disc_domain, - u32 priority) +static int tipc_enable_bearer(struct net *net, const char *name, + u32 disc_domain, u32 priority) { struct tipc_net *tn = net_generic(net, tipc_net_id); struct tipc_bearer *b_ptr; @@ -393,22 +393,6 @@ static void bearer_disable(struct net *net, struct tipc_bearer *b_ptr, kfree_rcu(b_ptr, rcu); } -int tipc_disable_bearer(struct net *net, const char *name) -{ - struct tipc_bearer *b_ptr; - int res; - - b_ptr = tipc_bearer_find(net, name); - if (b_ptr == NULL) { - pr_warn("Attempt to disable unknown bearer <%s>\n", name); - res = -EINVAL; - } else { - bearer_disable(net, b_ptr, false); - res = 0; - } - return res; -} - int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b) { struct net_device *dev; @@ -756,7 +740,7 @@ int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info) char *name; struct tipc_bearer *bearer; struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; - struct net *net = genl_info_net(info); + struct net *net = sock_net(skb->sk); if (!info->attrs[TIPC_NLA_BEARER]) return -EINVAL; @@ -787,11 +771,11 @@ int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info) int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info) { - struct net *net = genl_info_net(info); - struct tipc_net *tn = net_generic(net, tipc_net_id); int err; char *bearer; struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; + struct net *net = sock_net(skb->sk); + struct tipc_net *tn = net_generic(net, tipc_net_id); u32 domain; u32 prio; diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index 956858276d93..06f25d144871 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -173,9 +173,6 @@ struct tipc_bearer_names { */ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr); -int tipc_enable_bearer(struct net *net, const char *bearer_name, - u32 disc_domain, u32 priority); -int tipc_disable_bearer(struct net *net, const char *name); /* * Routines made available to TIPC by supported media types diff --git a/net/tipc/config.c b/net/tipc/config.c index 52e84b0ac48a..f8cd5e1b545f 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -134,33 +134,6 @@ static struct sk_buff *tipc_show_stats(void) return buf; } -static struct sk_buff *cfg_enable_bearer(struct net *net) -{ - struct tipc_bearer_config *args; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_CONFIG)) - return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - args = (struct tipc_bearer_config *)TLV_DATA(req_tlv_area); - if (tipc_enable_bearer(net, args->name, - ntohl(args->disc_domain), - ntohl(args->priority))) - return tipc_cfg_reply_error_string("unable to enable bearer"); - - return tipc_cfg_reply_none(); -} - -static struct sk_buff *cfg_disable_bearer(struct net *net) -{ - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_NAME)) - return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - if (tipc_disable_bearer(net, (char *)TLV_DATA(req_tlv_area))) - return tipc_cfg_reply_error_string("unable to disable bearer"); - - return tipc_cfg_reply_none(); -} - static struct sk_buff *cfg_set_own_addr(struct net *net) { struct tipc_net *tn = net_generic(net, tipc_net_id); @@ -267,12 +240,6 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, rep_tlv_buf = tipc_link_cmd_config(net, req_tlv_area, req_tlv_space, cmd); break; - case TIPC_CMD_ENABLE_BEARER: - rep_tlv_buf = cfg_enable_bearer(net); - break; - case TIPC_CMD_DISABLE_BEARER: - rep_tlv_buf = cfg_disable_bearer(net); - break; case TIPC_CMD_SET_NODE_ADDR: rep_tlv_buf = cfg_set_own_addr(net); break; diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index bd75ea290e3a..12b0f4424797 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -49,6 +49,7 @@ struct tipc_nl_compat_msg { u16 cmd; int rep_size; + int req_type; struct sk_buff *rep; struct tlv_desc *req; struct sock *dst_sk; @@ -59,6 +60,11 @@ struct tipc_nl_compat_cmd_dump { int (*format)(struct tipc_nl_compat_msg *msg, struct nlattr **attrs); }; +struct tipc_nl_compat_cmd_doit { + int (*doit)(struct sk_buff *skb, struct genl_info *info); + int (*transcode)(struct sk_buff *skb, struct tipc_nl_compat_msg *msg); +}; + static int tipc_skb_tailroom(struct sk_buff *skb) { int tailroom; @@ -213,6 +219,78 @@ static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, return err; } +static int __tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd, + struct tipc_nl_compat_msg *msg) +{ + int err; + struct sk_buff *doit_buf; + struct sk_buff *trans_buf; + struct nlattr **attrbuf; + struct genl_info info; + + trans_buf = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!trans_buf) + return -ENOMEM; + + err = (*cmd->transcode)(trans_buf, msg); + if (err) + goto trans_out; + + attrbuf = kmalloc((tipc_genl_family.maxattr + 1) * + sizeof(struct nlattr *), GFP_KERNEL); + if (!attrbuf) { + err = -ENOMEM; + goto trans_out; + } + + err = nla_parse(attrbuf, tipc_genl_family.maxattr, + (const struct nlattr *)trans_buf->data, + trans_buf->len, NULL); + if (err) + goto parse_out; + + doit_buf = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!doit_buf) { + err = -ENOMEM; + goto parse_out; + } + + doit_buf->sk = msg->dst_sk; + + memset(&info, 0, sizeof(info)); + info.attrs = attrbuf; + + err = (*cmd->doit)(doit_buf, &info); + + kfree_skb(doit_buf); +parse_out: + kfree(attrbuf); +trans_out: + kfree_skb(trans_buf); + + return err; +} + +static int tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd, + struct tipc_nl_compat_msg *msg) +{ + int err; + + if (msg->req_type && !TLV_CHECK_TYPE(msg->req, msg->req_type)) + return -EINVAL; + + err = __tipc_nl_compat_doit(cmd, msg); + if (err) + return err; + + /* The legacy API considered an empty message a success message */ + msg->rep = tipc_tlv_alloc(0); + if (!msg->rep) + return -ENOMEM; + + return 0; +} + static int tipc_nl_compat_bearer_dump(struct tipc_nl_compat_msg *msg, struct nlattr **attrs) { @@ -226,11 +304,65 @@ static int tipc_nl_compat_bearer_dump(struct tipc_nl_compat_msg *msg, nla_len(bearer[TIPC_NLA_BEARER_NAME])); } +static int tipc_nl_compat_bearer_enable(struct sk_buff *skb, + struct tipc_nl_compat_msg *msg) +{ + struct nlattr *prop; + struct nlattr *bearer; + struct tipc_bearer_config *b; + + b = (struct tipc_bearer_config *)TLV_DATA(msg->req); + + bearer = nla_nest_start(skb, TIPC_NLA_BEARER); + if (!bearer) + return -EMSGSIZE; + + if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, b->name)) + return -EMSGSIZE; + + if (nla_put_u32(skb, TIPC_NLA_BEARER_DOMAIN, ntohl(b->disc_domain))) + return -EMSGSIZE; + + if (ntohl(b->priority) <= TIPC_MAX_LINK_PRI) { + prop = nla_nest_start(skb, TIPC_NLA_BEARER_PROP); + if (!prop) + return -EMSGSIZE; + if (nla_put_u32(skb, TIPC_NLA_PROP_PRIO, ntohl(b->priority))) + return -EMSGSIZE; + nla_nest_end(skb, prop); + } + nla_nest_end(skb, bearer); + + return 0; +} + +static int tipc_nl_compat_bearer_disable(struct sk_buff *skb, + struct tipc_nl_compat_msg *msg) +{ + char *name; + struct nlattr *bearer; + + name = (char *)TLV_DATA(msg->req); + + bearer = nla_nest_start(skb, TIPC_NLA_BEARER); + if (!bearer) + return -EMSGSIZE; + + if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, name)) + return -EMSGSIZE; + + nla_nest_end(skb, bearer); + + return 0; +} + static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) { struct tipc_nl_compat_cmd_dump dump; + struct tipc_nl_compat_cmd_doit doit; memset(&dump, 0, sizeof(dump)); + memset(&doit, 0, sizeof(doit)); switch (msg->cmd) { case TIPC_CMD_GET_BEARER_NAMES: @@ -238,6 +370,16 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) dump.dumpit = tipc_nl_bearer_dump; dump.format = tipc_nl_compat_bearer_dump; return tipc_nl_compat_dumpit(&dump, msg); + case TIPC_CMD_ENABLE_BEARER: + msg->req_type = TIPC_TLV_BEARER_CONFIG; + doit.doit = tipc_nl_bearer_enable; + doit.transcode = tipc_nl_compat_bearer_enable; + return tipc_nl_compat_doit(&doit, msg); + case TIPC_CMD_DISABLE_BEARER: + msg->req_type = TIPC_TLV_BEARER_NAME; + doit.doit = tipc_nl_bearer_disable; + doit.transcode = tipc_nl_compat_bearer_disable; + return tipc_nl_compat_doit(&doit, msg); } return -EOPNOTSUPP; @@ -335,6 +477,8 @@ static int tipc_nl_compat_tmp_wrap(struct sk_buff *skb, struct genl_info *info) switch (req->cmd) { case TIPC_CMD_GET_BEARER_NAMES: + case TIPC_CMD_ENABLE_BEARER: + case TIPC_CMD_DISABLE_BEARER: return tipc_nl_compat_recv(skb, info); } From f2b3b2d4ccbf9666f5f42a21347cd1aaa532b2fa Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:06 +0100 Subject: [PATCH 04/17] 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 Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- include/uapi/linux/tipc_config.h | 10 ++ net/tipc/bcast.c | 43 ------- net/tipc/bcast.h | 1 - net/tipc/config.c | 4 - net/tipc/link.c | 141 --------------------- net/tipc/link.h | 3 - net/tipc/netlink_compat.c | 205 +++++++++++++++++++++++++++++++ 7 files changed, 215 insertions(+), 192 deletions(-) diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h index f9226566c1b8..087b0ef82c07 100644 --- a/include/uapi/linux/tipc_config.h +++ b/include/uapi/linux/tipc_config.h @@ -277,11 +277,21 @@ static inline int TLV_GET_LEN(struct tlv_desc *tlv) return ntohs(tlv->tlv_len); } +static inline void TLV_SET_LEN(struct tlv_desc *tlv, __u16 len) +{ + tlv->tlv_len = htons(len); +} + static inline int TLV_CHECK_TYPE(struct tlv_desc *tlv, __u16 type) { return (ntohs(tlv->tlv_type) == type); } +static inline void TLV_SET_TYPE(struct tlv_desc *tlv, __u16 type) +{ + tlv->tlv_type = htons(type); +} + static inline int TLV_SET(void *tlv, __u16 type, void *data, __u16 len) { struct tlv_desc *tlv_ptr; diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index e96fd6a6d5c2..3e41704832de 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -860,49 +860,6 @@ msg_full: return -EMSGSIZE; } -int tipc_bclink_stats(struct net *net, char *buf, const u32 buf_size) -{ - int ret; - struct tipc_stats *s; - struct tipc_net *tn = net_generic(net, tipc_net_id); - struct tipc_link *bcl = tn->bcl; - - if (!bcl) - return 0; - - tipc_bclink_lock(net); - - s = &bcl->stats; - - ret = tipc_snprintf(buf, buf_size, "Link <%s>\n" - " Window:%u packets\n", - bcl->name, bcl->queue_limit[0]); - ret += tipc_snprintf(buf + ret, buf_size - ret, - " RX packets:%u fragments:%u/%u bundles:%u/%u\n", - s->recv_info, s->recv_fragments, - s->recv_fragmented, s->recv_bundles, - s->recv_bundled); - ret += tipc_snprintf(buf + ret, buf_size - ret, - " TX packets:%u fragments:%u/%u bundles:%u/%u\n", - s->sent_info, s->sent_fragments, - s->sent_fragmented, s->sent_bundles, - s->sent_bundled); - ret += tipc_snprintf(buf + ret, buf_size - ret, - " RX naks:%u defs:%u dups:%u\n", - s->recv_nacks, s->deferred_recv, s->duplicates); - ret += tipc_snprintf(buf + ret, buf_size - ret, - " TX naks:%u acks:%u dups:%u\n", - s->sent_nacks, s->sent_acks, s->retransmitted); - ret += tipc_snprintf(buf + ret, buf_size - ret, - " Congestion link:%u Send queue max:%u avg:%u\n", - s->link_congs, s->max_queue_sz, - s->queue_sz_counts ? - (s->accu_queue_sz / s->queue_sz_counts) : 0); - - tipc_bclink_unlock(net); - return ret; -} - int tipc_bclink_reset_stats(struct net *net) { 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); u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr); void tipc_bclink_update_link_state(struct tipc_node *node, u32 last_sent); -int tipc_bclink_stats(struct net *net, char *stats_buf, const u32 buf_size); int tipc_bclink_reset_stats(struct net *net); int tipc_bclink_set_queue_limits(struct net *net, u32 limit); void tipc_bcbearer_sort(struct net *net, struct tipc_node_map *nm_ptr, diff --git a/net/tipc/config.c b/net/tipc/config.c index f8cd5e1b545f..67b76ee847f3 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -213,10 +213,6 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, rep_tlv_buf = tipc_node_get_links(net, req_tlv_area, req_tlv_space); break; - case TIPC_CMD_SHOW_LINK_STATS: - rep_tlv_buf = tipc_link_cmd_show_stats(net, req_tlv_area, - req_tlv_space); - break; case TIPC_CMD_RESET_LINK_STATS: rep_tlv_buf = tipc_link_cmd_reset_stats(net, req_tlv_area, req_tlv_space); diff --git a/net/tipc/link.c b/net/tipc/link.c index 466f28fcf215..2622fb99344a 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -2146,147 +2146,6 @@ struct sk_buff *tipc_link_cmd_reset_stats(struct net *net, return tipc_cfg_reply_none(); } -/** - * percent - convert count to a percentage of total (rounding up or down) - */ -static u32 percent(u32 count, u32 total) -{ - return (count * 100 + (total / 2)) / total; -} - -/** - * tipc_link_stats - print link statistics - * @net: the applicable net namespace - * @name: link name - * @buf: print buffer area - * @buf_size: size of print buffer area - * - * Returns length of print buffer data string (or 0 if error) - */ -static int tipc_link_stats(struct net *net, const char *name, char *buf, - const u32 buf_size) -{ - struct tipc_link *l; - struct tipc_stats *s; - struct tipc_node *node; - char *status; - u32 profile_total = 0; - unsigned int bearer_id; - int ret; - - if (!strcmp(name, tipc_bclink_name)) - return tipc_bclink_stats(net, buf, buf_size); - - node = tipc_link_find_owner(net, name, &bearer_id); - if (!node) - return 0; - - tipc_node_lock(node); - - l = node->links[bearer_id]; - if (!l) { - tipc_node_unlock(node); - return 0; - } - - s = &l->stats; - - if (tipc_link_is_active(l)) - status = "ACTIVE"; - else if (tipc_link_is_up(l)) - status = "STANDBY"; - else - status = "DEFUNCT"; - - ret = tipc_snprintf(buf, buf_size, "Link <%s>\n" - " %s MTU:%u Priority:%u Tolerance:%u ms" - " Window:%u packets\n", - l->name, status, l->max_pkt, l->priority, - l->tolerance, l->queue_limit[0]); - - ret += tipc_snprintf(buf + ret, buf_size - ret, - " RX packets:%u fragments:%u/%u bundles:%u/%u\n", - l->next_in_no - s->recv_info, s->recv_fragments, - s->recv_fragmented, s->recv_bundles, - s->recv_bundled); - - ret += tipc_snprintf(buf + ret, buf_size - ret, - " TX packets:%u fragments:%u/%u bundles:%u/%u\n", - l->next_out_no - s->sent_info, s->sent_fragments, - s->sent_fragmented, s->sent_bundles, - s->sent_bundled); - - profile_total = s->msg_length_counts; - if (!profile_total) - profile_total = 1; - - ret += tipc_snprintf(buf + ret, buf_size - ret, - " TX profile sample:%u packets average:%u octets\n" - " 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% " - "-16384:%u%% -32768:%u%% -66000:%u%%\n", - s->msg_length_counts, - s->msg_lengths_total / profile_total, - percent(s->msg_length_profile[0], profile_total), - percent(s->msg_length_profile[1], profile_total), - percent(s->msg_length_profile[2], profile_total), - percent(s->msg_length_profile[3], profile_total), - percent(s->msg_length_profile[4], profile_total), - percent(s->msg_length_profile[5], profile_total), - percent(s->msg_length_profile[6], profile_total)); - - ret += tipc_snprintf(buf + ret, buf_size - ret, - " RX states:%u probes:%u naks:%u defs:%u" - " dups:%u\n", s->recv_states, s->recv_probes, - s->recv_nacks, s->deferred_recv, s->duplicates); - - ret += tipc_snprintf(buf + ret, buf_size - ret, - " TX states:%u probes:%u naks:%u acks:%u" - " dups:%u\n", s->sent_states, s->sent_probes, - s->sent_nacks, s->sent_acks, s->retransmitted); - - ret += tipc_snprintf(buf + ret, buf_size - ret, - " Congestion link:%u Send queue" - " max:%u avg:%u\n", s->link_congs, - s->max_queue_sz, s->queue_sz_counts ? - (s->accu_queue_sz / s->queue_sz_counts) : 0); - - tipc_node_unlock(node); - return ret; -} - -struct sk_buff *tipc_link_cmd_show_stats(struct net *net, - const void *req_tlv_area, - int req_tlv_space) -{ - struct sk_buff *buf; - struct tlv_desc *rep_tlv; - int str_len; - int pb_len; - char *pb; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME)) - return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); - if (!buf) - return NULL; - - rep_tlv = (struct tlv_desc *)buf->data; - pb = TLV_DATA(rep_tlv); - pb_len = ULTRA_STRING_MAX_LEN; - str_len = tipc_link_stats(net, (char *)TLV_DATA(req_tlv_area), - pb, pb_len); - if (!str_len) { - kfree_skb(buf); - return tipc_cfg_reply_error_string("link not found"); - } - str_len += 1; /* for "\0" */ - skb_put(buf, TLV_SPACE(str_len)); - TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); - - return buf; -} - static void link_print(struct tipc_link *l_ptr, const char *str) { struct tipc_net *tn = net_generic(l_ptr->owner->net, tipc_net_id); diff --git a/net/tipc/link.h b/net/tipc/link.h index 34d3f55c4cea..8c8340cf991f 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -217,9 +217,6 @@ int tipc_link_is_active(struct tipc_link *l_ptr); void tipc_link_purge_queues(struct tipc_link *l_ptr); struct sk_buff *tipc_link_cmd_config(struct net *net, const void *req_tlv_area, int req_tlv_space, u16 cmd); -struct sk_buff *tipc_link_cmd_show_stats(struct net *net, - const void *req_tlv_area, - int req_tlv_space); struct sk_buff *tipc_link_cmd_reset_stats(struct net *net, const void *req_tlv_area, int req_tlv_space); diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 12b0f4424797..899bd94da467 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -34,6 +34,7 @@ #include "core.h" #include "config.h" #include "bearer.h" +#include "link.h" #include #include @@ -48,6 +49,7 @@ struct tipc_nl_compat_msg { u16 cmd; + int rep_type; int rep_size; int req_type; struct sk_buff *rep; @@ -95,6 +97,40 @@ static int tipc_add_tlv(struct sk_buff *skb, u16 type, void *data, u16 len) return 0; } +static void tipc_tlv_init(struct sk_buff *skb, u16 type) +{ + struct tlv_desc *tlv = (struct tlv_desc *)skb->data; + + TLV_SET_LEN(tlv, 0); + TLV_SET_TYPE(tlv, type); + skb_put(skb, sizeof(struct tlv_desc)); +} + +static int tipc_tlv_sprintf(struct sk_buff *skb, const char *fmt, ...) +{ + int n; + u16 len; + u32 rem; + char *buf; + struct tlv_desc *tlv; + va_list args; + + rem = tipc_skb_tailroom(skb); + + tlv = (struct tlv_desc *)skb->data; + len = TLV_GET_LEN(tlv); + buf = TLV_DATA(tlv) + len; + + va_start(args, fmt); + n = vscnprintf(buf, rem, fmt, args); + va_end(args); + + TLV_SET_LEN(tlv, n + len); + skb_put(skb, n); + + return n; +} + static struct sk_buff *tipc_tlv_alloc(int size) { int hdr_len; @@ -200,10 +236,16 @@ static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, int err; struct sk_buff *arg; + if (msg->req_type && !TLV_CHECK_TYPE(msg->req, msg->req_type)) + return -EINVAL; + msg->rep = tipc_tlv_alloc(msg->rep_size); if (!msg->rep) return -ENOMEM; + if (msg->rep_type) + tipc_tlv_init(msg->rep, msg->rep_type); + arg = nlmsg_new(0, GFP_KERNEL); if (!arg) { kfree_skb(msg->rep); @@ -356,6 +398,161 @@ static int tipc_nl_compat_bearer_disable(struct sk_buff *skb, return 0; } +static inline u32 perc(u32 count, u32 total) +{ + return (count * 100 + (total / 2)) / total; +} + +static void __fill_bc_link_stat(struct tipc_nl_compat_msg *msg, + struct nlattr *prop[], struct nlattr *stats[]) +{ + tipc_tlv_sprintf(msg->rep, " Window:%u packets\n", + nla_get_u32(prop[TIPC_NLA_PROP_WIN])); + + tipc_tlv_sprintf(msg->rep, + " RX packets:%u fragments:%u/%u bundles:%u/%u\n", + nla_get_u32(stats[TIPC_NLA_STATS_RX_INFO]), + nla_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]), + nla_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]), + nla_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]), + nla_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED])); + + tipc_tlv_sprintf(msg->rep, + " TX packets:%u fragments:%u/%u bundles:%u/%u\n", + nla_get_u32(stats[TIPC_NLA_STATS_TX_INFO]), + nla_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]), + nla_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]), + nla_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]), + nla_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED])); + + tipc_tlv_sprintf(msg->rep, " RX naks:%u defs:%u dups:%u\n", + nla_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]), + nla_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]), + nla_get_u32(stats[TIPC_NLA_STATS_DUPLICATES])); + + tipc_tlv_sprintf(msg->rep, " TX naks:%u acks:%u dups:%u\n", + nla_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]), + nla_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]), + nla_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED])); + + tipc_tlv_sprintf(msg->rep, + " Congestion link:%u Send queue max:%u avg:%u", + nla_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]), + nla_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]), + nla_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE])); +} + +static int tipc_nl_compat_link_stat_dump(struct tipc_nl_compat_msg *msg, + struct nlattr **attrs) +{ + char *name; + struct nlattr *link[TIPC_NLA_LINK_MAX + 1]; + struct nlattr *prop[TIPC_NLA_PROP_MAX + 1]; + struct nlattr *stats[TIPC_NLA_STATS_MAX + 1]; + + nla_parse_nested(link, TIPC_NLA_LINK_MAX, attrs[TIPC_NLA_LINK], NULL); + + nla_parse_nested(prop, TIPC_NLA_PROP_MAX, link[TIPC_NLA_LINK_PROP], + NULL); + + nla_parse_nested(stats, TIPC_NLA_STATS_MAX, link[TIPC_NLA_LINK_STATS], + NULL); + + name = (char *)TLV_DATA(msg->req); + if (strcmp(name, nla_data(link[TIPC_NLA_LINK_NAME])) != 0) + return 0; + + tipc_tlv_sprintf(msg->rep, "\nLink <%s>\n", + nla_data(link[TIPC_NLA_LINK_NAME])); + + if (link[TIPC_NLA_LINK_BROADCAST]) { + __fill_bc_link_stat(msg, prop, stats); + return 0; + } + + if (link[TIPC_NLA_LINK_ACTIVE]) + tipc_tlv_sprintf(msg->rep, " ACTIVE"); + else if (link[TIPC_NLA_LINK_UP]) + tipc_tlv_sprintf(msg->rep, " STANDBY"); + else + tipc_tlv_sprintf(msg->rep, " DEFUNCT"); + + tipc_tlv_sprintf(msg->rep, " MTU:%u Priority:%u", + nla_get_u32(link[TIPC_NLA_LINK_MTU]), + nla_get_u32(prop[TIPC_NLA_PROP_PRIO])); + + tipc_tlv_sprintf(msg->rep, " Tolerance:%u ms Window:%u packets\n", + nla_get_u32(prop[TIPC_NLA_PROP_TOL]), + nla_get_u32(prop[TIPC_NLA_PROP_WIN])); + + tipc_tlv_sprintf(msg->rep, + " RX packets:%u fragments:%u/%u bundles:%u/%u\n", + nla_get_u32(link[TIPC_NLA_LINK_RX]) - + nla_get_u32(stats[TIPC_NLA_STATS_RX_INFO]), + nla_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]), + nla_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]), + nla_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]), + nla_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED])); + + tipc_tlv_sprintf(msg->rep, + " TX packets:%u fragments:%u/%u bundles:%u/%u\n", + nla_get_u32(link[TIPC_NLA_LINK_TX]) - + nla_get_u32(stats[TIPC_NLA_STATS_TX_INFO]), + nla_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]), + nla_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]), + nla_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]), + nla_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED])); + + tipc_tlv_sprintf(msg->rep, + " TX profile sample:%u packets average:%u octets\n", + nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_CNT]), + nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_TOT]) / + nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])); + + tipc_tlv_sprintf(msg->rep, + " 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% ", + perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P0]), + nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])), + perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P1]), + nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])), + perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P2]), + nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])), + perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P3]), + nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT]))); + + tipc_tlv_sprintf(msg->rep, "-16384:%u%% -32768:%u%% -66000:%u%%\n", + perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P4]), + nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])), + perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P5]), + nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])), + perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P6]), + nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT]))); + + tipc_tlv_sprintf(msg->rep, + " RX states:%u probes:%u naks:%u defs:%u dups:%u\n", + nla_get_u32(stats[TIPC_NLA_STATS_RX_STATES]), + nla_get_u32(stats[TIPC_NLA_STATS_RX_PROBES]), + nla_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]), + nla_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]), + nla_get_u32(stats[TIPC_NLA_STATS_DUPLICATES])); + + tipc_tlv_sprintf(msg->rep, + " TX states:%u probes:%u naks:%u acks:%u dups:%u\n", + nla_get_u32(stats[TIPC_NLA_STATS_TX_STATES]), + nla_get_u32(stats[TIPC_NLA_STATS_TX_PROBES]), + nla_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]), + nla_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]), + nla_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED])); + + tipc_tlv_sprintf(msg->rep, + " Congestion link:%u Send queue max:%u avg:%u", + nla_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]), + nla_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]), + nla_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE])); + + return 0; +} + static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) { struct tipc_nl_compat_cmd_dump dump; @@ -380,6 +577,13 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) doit.doit = tipc_nl_bearer_disable; doit.transcode = tipc_nl_compat_bearer_disable; return tipc_nl_compat_doit(&doit, msg); + case TIPC_CMD_SHOW_LINK_STATS: + msg->req_type = TIPC_TLV_LINK_NAME; + msg->rep_size = ULTRA_STRING_MAX_LEN; + msg->rep_type = TIPC_TLV_ULTRA_STRING; + dump.dumpit = tipc_nl_link_dump; + dump.format = tipc_nl_compat_link_stat_dump; + return tipc_nl_compat_dumpit(&dump, msg); } return -EOPNOTSUPP; @@ -479,6 +683,7 @@ static int tipc_nl_compat_tmp_wrap(struct sk_buff *skb, struct genl_info *info) case TIPC_CMD_GET_BEARER_NAMES: case TIPC_CMD_ENABLE_BEARER: case TIPC_CMD_DISABLE_BEARER: + case TIPC_CMD_SHOW_LINK_STATS: return tipc_nl_compat_recv(skb, info); } From 357ebdbfca0baa9a8d8d85307393e9ec3406affc Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:07 +0100 Subject: [PATCH 05/17] tipc: convert legacy nl link dump to nl compat Convert TIPC_CMD_GET_LINKS to compat dumpit and remove global link counter solely used by the legacy API. Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/config.c | 4 --- net/tipc/netlink_compat.c | 23 ++++++++++++ net/tipc/node.c | 73 --------------------------------------- net/tipc/node.h | 2 -- 4 files changed, 23 insertions(+), 79 deletions(-) diff --git a/net/tipc/config.c b/net/tipc/config.c index 67b76ee847f3..1b17f5846e86 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -209,10 +209,6 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, rep_tlv_buf = tipc_node_get_nodes(net, req_tlv_area, req_tlv_space); break; - case TIPC_CMD_GET_LINKS: - rep_tlv_buf = tipc_node_get_links(net, req_tlv_area, - req_tlv_space); - break; case TIPC_CMD_RESET_LINK_STATS: rep_tlv_buf = tipc_link_cmd_reset_stats(net, req_tlv_area, req_tlv_space); diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 899bd94da467..bff9403899ed 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -553,6 +553,22 @@ static int tipc_nl_compat_link_stat_dump(struct tipc_nl_compat_msg *msg, return 0; } +static int tipc_nl_compat_link_dump(struct tipc_nl_compat_msg *msg, + struct nlattr **attrs) +{ + struct nlattr *link[TIPC_NLA_LINK_MAX + 1]; + struct tipc_link_info link_info; + + nla_parse_nested(link, TIPC_NLA_LINK_MAX, attrs[TIPC_NLA_LINK], NULL); + + link_info.dest = nla_get_flag(link[TIPC_NLA_LINK_DEST]); + link_info.up = htonl(nla_get_flag(link[TIPC_NLA_LINK_UP])); + strcpy(link_info.str, nla_data(link[TIPC_NLA_LINK_NAME])); + + return tipc_add_tlv(msg->rep, TIPC_TLV_LINK_INFO, + &link_info, sizeof(link_info)); +} + static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) { struct tipc_nl_compat_cmd_dump dump; @@ -584,6 +600,12 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) dump.dumpit = tipc_nl_link_dump; dump.format = tipc_nl_compat_link_stat_dump; return tipc_nl_compat_dumpit(&dump, msg); + case TIPC_CMD_GET_LINKS: + msg->req_type = TIPC_TLV_NET_ADDR; + msg->rep_size = ULTRA_STRING_MAX_LEN; + dump.dumpit = tipc_nl_link_dump; + dump.format = tipc_nl_compat_link_dump; + return tipc_nl_compat_dumpit(&dump, msg); } return -EOPNOTSUPP; @@ -684,6 +706,7 @@ static int tipc_nl_compat_tmp_wrap(struct sk_buff *skb, struct genl_info *info) case TIPC_CMD_ENABLE_BEARER: case TIPC_CMD_DISABLE_BEARER: case TIPC_CMD_SHOW_LINK_STATS: + case TIPC_CMD_GET_LINKS: return tipc_nl_compat_recv(skb, info); } diff --git a/net/tipc/node.c b/net/tipc/node.c index 995618d6da9d..46b87f77d342 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -319,27 +319,18 @@ int tipc_node_is_up(struct tipc_node *n_ptr) void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr) { - struct tipc_net *tn = net_generic(n_ptr->net, tipc_net_id); - n_ptr->links[l_ptr->bearer_id] = l_ptr; - spin_lock_bh(&tn->node_list_lock); - tn->num_links++; - spin_unlock_bh(&tn->node_list_lock); n_ptr->link_cnt++; } void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr) { - struct tipc_net *tn = net_generic(n_ptr->net, tipc_net_id); int i; for (i = 0; i < MAX_BEARERS; i++) { if (l_ptr != n_ptr->links[i]) continue; n_ptr->links[i] = NULL; - spin_lock_bh(&tn->node_list_lock); - tn->num_links--; - spin_unlock_bh(&tn->node_list_lock); n_ptr->link_cnt--; } } @@ -467,70 +458,6 @@ struct sk_buff *tipc_node_get_nodes(struct net *net, const void *req_tlv_area, return buf; } -struct sk_buff *tipc_node_get_links(struct net *net, const void *req_tlv_area, - int req_tlv_space) -{ - struct tipc_net *tn = net_generic(net, tipc_net_id); - u32 domain; - struct sk_buff *buf; - struct tipc_node *n_ptr; - struct tipc_link_info link_info; - u32 payload_size; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) - return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - domain = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); - if (!tipc_addr_domain_valid(domain)) - return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE - " (network address)"); - - if (!tn->own_addr) - return tipc_cfg_reply_none(); - - spin_lock_bh(&tn->node_list_lock); - /* Get space for all unicast links + broadcast link */ - payload_size = TLV_SPACE((sizeof(link_info)) * (tn->num_links + 1)); - if (payload_size > 32768u) { - spin_unlock_bh(&tn->node_list_lock); - return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (too many links)"); - } - spin_unlock_bh(&tn->node_list_lock); - - buf = tipc_cfg_reply_alloc(payload_size); - if (!buf) - return NULL; - - /* Add TLV for broadcast link */ - link_info.dest = htonl(tipc_cluster_mask(tn->own_addr)); - link_info.up = htonl(1); - strlcpy(link_info.str, tipc_bclink_name, TIPC_MAX_LINK_NAME); - tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, &link_info, sizeof(link_info)); - - /* Add TLVs for any other links in scope */ - rcu_read_lock(); - list_for_each_entry_rcu(n_ptr, &tn->node_list, list) { - u32 i; - - if (!tipc_in_scope(domain, n_ptr->addr)) - continue; - tipc_node_lock(n_ptr); - for (i = 0; i < MAX_BEARERS; i++) { - if (!n_ptr->links[i]) - continue; - link_info.dest = htonl(n_ptr->addr); - link_info.up = htonl(tipc_link_is_up(n_ptr->links[i])); - strcpy(link_info.str, n_ptr->links[i]->name); - tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, - &link_info, sizeof(link_info)); - } - tipc_node_unlock(n_ptr); - } - rcu_read_unlock(); - return buf; -} - /** * tipc_node_get_linkname - get the name of a link * diff --git a/net/tipc/node.h b/net/tipc/node.h index 20ec13f9bede..59dafee61aa0 100644 --- a/net/tipc/node.h +++ b/net/tipc/node.h @@ -142,8 +142,6 @@ void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr); void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr); int tipc_node_active_links(struct tipc_node *n_ptr); int tipc_node_is_up(struct tipc_node *n_ptr); -struct sk_buff *tipc_node_get_links(struct net *net, const void *req_tlv_area, - int req_tlv_space); struct sk_buff *tipc_node_get_nodes(struct net *net, const void *req_tlv_area, int req_tlv_space); int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 node, From 37e2d4843f9e2f5aad6bf3be5dad174f2838f375 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:08 +0100 Subject: [PATCH 06/17] tipc: convert legacy nl link prop set to nl compat Convert setting of link proprieties to compat doit calls. Commands converted in this patch: TIPC_CMD_SET_LINK_TOL TIPC_CMD_SET_LINK_PRI TIPC_CMD_SET_LINK_WINDOW Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/config.c | 6 -- net/tipc/link.c | 146 +------------------------------------- net/tipc/link.h | 2 - net/tipc/netlink_compat.c | 47 ++++++++++++ 4 files changed, 48 insertions(+), 153 deletions(-) diff --git a/net/tipc/config.c b/net/tipc/config.c index 1b17f5846e86..75a130e493f5 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -226,12 +226,6 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, case TIPC_CMD_SHOW_STATS: rep_tlv_buf = tipc_show_stats(); break; - case TIPC_CMD_SET_LINK_TOL: - case TIPC_CMD_SET_LINK_PRI: - case TIPC_CMD_SET_LINK_WINDOW: - rep_tlv_buf = tipc_link_cmd_config(net, req_tlv_area, - req_tlv_space, cmd); - break; case TIPC_CMD_SET_NODE_ADDR: rep_tlv_buf = cfg_set_own_addr(net); break; diff --git a/net/tipc/link.c b/net/tipc/link.c index 2622fb99344a..ec136b5cc339 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -1958,150 +1958,6 @@ static struct tipc_node *tipc_link_find_owner(struct net *net, return found_node; } -/** - * link_value_is_valid -- validate proposed link tolerance/priority/window - * - * @cmd: value type (TIPC_CMD_SET_LINK_*) - * @new_value: the new value - * - * Returns 1 if value is within range, 0 if not. - */ -static int link_value_is_valid(u16 cmd, u32 new_value) -{ - switch (cmd) { - case TIPC_CMD_SET_LINK_TOL: - return (new_value >= TIPC_MIN_LINK_TOL) && - (new_value <= TIPC_MAX_LINK_TOL); - case TIPC_CMD_SET_LINK_PRI: - return (new_value <= TIPC_MAX_LINK_PRI); - case TIPC_CMD_SET_LINK_WINDOW: - return (new_value >= TIPC_MIN_LINK_WIN) && - (new_value <= TIPC_MAX_LINK_WIN); - } - return 0; -} - -/** - * link_cmd_set_value - change priority/tolerance/window for link/bearer/media - * @net: the applicable net namespace - * @name: ptr to link, bearer, or media name - * @new_value: new value of link, bearer, or media setting - * @cmd: which link, bearer, or media attribute to set (TIPC_CMD_SET_LINK_*) - * - * Caller must hold RTNL lock to ensure link/bearer/media is not deleted. - * - * Returns 0 if value updated and negative value on error. - */ -static int link_cmd_set_value(struct net *net, const char *name, u32 new_value, - u16 cmd) -{ - struct tipc_node *node; - struct tipc_link *l_ptr; - struct tipc_bearer *b_ptr; - struct tipc_media *m_ptr; - int bearer_id; - int res = 0; - - node = tipc_link_find_owner(net, name, &bearer_id); - if (node) { - tipc_node_lock(node); - l_ptr = node->links[bearer_id]; - - if (l_ptr) { - switch (cmd) { - case TIPC_CMD_SET_LINK_TOL: - link_set_supervision_props(l_ptr, new_value); - tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, - new_value, 0, 0); - break; - case TIPC_CMD_SET_LINK_PRI: - l_ptr->priority = new_value; - tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, - 0, new_value, 0); - break; - case TIPC_CMD_SET_LINK_WINDOW: - tipc_link_set_queue_limits(l_ptr, new_value); - break; - default: - res = -EINVAL; - break; - } - } - tipc_node_unlock(node); - return res; - } - - b_ptr = tipc_bearer_find(net, name); - if (b_ptr) { - switch (cmd) { - case TIPC_CMD_SET_LINK_TOL: - b_ptr->tolerance = new_value; - break; - case TIPC_CMD_SET_LINK_PRI: - b_ptr->priority = new_value; - break; - case TIPC_CMD_SET_LINK_WINDOW: - b_ptr->window = new_value; - break; - default: - res = -EINVAL; - break; - } - return res; - } - - m_ptr = tipc_media_find(name); - if (!m_ptr) - return -ENODEV; - switch (cmd) { - case TIPC_CMD_SET_LINK_TOL: - m_ptr->tolerance = new_value; - break; - case TIPC_CMD_SET_LINK_PRI: - m_ptr->priority = new_value; - break; - case TIPC_CMD_SET_LINK_WINDOW: - m_ptr->window = new_value; - break; - default: - res = -EINVAL; - break; - } - return res; -} - -struct sk_buff *tipc_link_cmd_config(struct net *net, const void *req_tlv_area, - int req_tlv_space, u16 cmd) -{ - struct tipc_link_config *args; - u32 new_value; - int res; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_CONFIG)) - return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - args = (struct tipc_link_config *)TLV_DATA(req_tlv_area); - new_value = ntohl(args->value); - - if (!link_value_is_valid(cmd, new_value)) - return tipc_cfg_reply_error_string( - "cannot change, value invalid"); - - if (!strcmp(args->name, tipc_bclink_name)) { - if ((cmd == TIPC_CMD_SET_LINK_WINDOW) && - (tipc_bclink_set_queue_limits(net, new_value) == 0)) - return tipc_cfg_reply_none(); - return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (cannot change setting on broadcast link)"); - } - - res = link_cmd_set_value(net, args->name, new_value, cmd); - if (res) - return tipc_cfg_reply_error_string("cannot change link setting"); - - return tipc_cfg_reply_none(); -} - /** * link_reset_statistics - reset link statistics * @l_ptr: pointer to link @@ -2216,7 +2072,7 @@ int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info) struct tipc_link *link; struct tipc_node *node; struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1]; - struct net *net = genl_info_net(info); + struct net *net = sock_net(skb->sk); if (!info->attrs[TIPC_NLA_LINK]) return -EINVAL; diff --git a/net/tipc/link.h b/net/tipc/link.h index 8c8340cf991f..6eb9d606063b 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -215,8 +215,6 @@ void tipc_link_reset_fragments(struct tipc_link *l_ptr); int tipc_link_is_up(struct tipc_link *l_ptr); int tipc_link_is_active(struct tipc_link *l_ptr); void tipc_link_purge_queues(struct tipc_link *l_ptr); -struct sk_buff *tipc_link_cmd_config(struct net *net, const void *req_tlv_area, - int req_tlv_space, u16 cmd); struct sk_buff *tipc_link_cmd_reset_stats(struct net *net, const void *req_tlv_area, int req_tlv_space); diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index bff9403899ed..056532b41e7e 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -569,6 +569,43 @@ static int tipc_nl_compat_link_dump(struct tipc_nl_compat_msg *msg, &link_info, sizeof(link_info)); } +static int tipc_nl_compat_link_set(struct sk_buff *skb, + struct tipc_nl_compat_msg *msg) +{ + struct nlattr *link; + struct nlattr *prop; + struct tipc_link_config *lc; + + lc = (struct tipc_link_config *)TLV_DATA(msg->req); + + link = nla_nest_start(skb, TIPC_NLA_LINK); + if (!link) + return -EMSGSIZE; + + if (nla_put_string(skb, TIPC_NLA_LINK_NAME, lc->name)) + return -EMSGSIZE; + + prop = nla_nest_start(skb, TIPC_NLA_LINK_PROP); + if (!prop) + return -EMSGSIZE; + + if (msg->cmd == TIPC_CMD_SET_LINK_PRI) { + if (nla_put_u32(skb, TIPC_NLA_PROP_PRIO, ntohl(lc->value))) + return -EMSGSIZE; + } else if (msg->cmd == TIPC_CMD_SET_LINK_TOL) { + if (nla_put_u32(skb, TIPC_NLA_PROP_TOL, ntohl(lc->value))) + return -EMSGSIZE; + } else if (msg->cmd == TIPC_CMD_SET_LINK_WINDOW) { + if (nla_put_u32(skb, TIPC_NLA_PROP_WIN, ntohl(lc->value))) + return -EMSGSIZE; + } + + nla_nest_end(skb, prop); + nla_nest_end(skb, link); + + return 0; +} + static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) { struct tipc_nl_compat_cmd_dump dump; @@ -606,6 +643,13 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) dump.dumpit = tipc_nl_link_dump; dump.format = tipc_nl_compat_link_dump; return tipc_nl_compat_dumpit(&dump, msg); + case TIPC_CMD_SET_LINK_TOL: + case TIPC_CMD_SET_LINK_PRI: + case TIPC_CMD_SET_LINK_WINDOW: + msg->req_type = TIPC_TLV_LINK_CONFIG; + doit.doit = tipc_nl_link_set; + doit.transcode = tipc_nl_compat_link_set; + return tipc_nl_compat_doit(&doit, msg); } return -EOPNOTSUPP; @@ -707,6 +751,9 @@ static int tipc_nl_compat_tmp_wrap(struct sk_buff *skb, struct genl_info *info) case TIPC_CMD_DISABLE_BEARER: case TIPC_CMD_SHOW_LINK_STATS: case TIPC_CMD_GET_LINKS: + case TIPC_CMD_SET_LINK_TOL: + case TIPC_CMD_SET_LINK_PRI: + case TIPC_CMD_SET_LINK_WINDOW: return tipc_nl_compat_recv(skb, info); } From 1817877b3cd7b4dc73e4a1514d5f48eaa3989ec9 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:09 +0100 Subject: [PATCH 07/17] tipc: convert legacy nl link stat reset to nl compat Convert TIPC_CMD_RESET_LINK_STATS to compat doit. Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/config.c | 4 ---- net/tipc/link.c | 35 +---------------------------------- net/tipc/link.h | 3 --- net/tipc/netlink_compat.c | 26 ++++++++++++++++++++++++++ 4 files changed, 27 insertions(+), 41 deletions(-) diff --git a/net/tipc/config.c b/net/tipc/config.c index 75a130e493f5..11c16d191fa2 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -209,10 +209,6 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, rep_tlv_buf = tipc_node_get_nodes(net, req_tlv_area, req_tlv_space); break; - case TIPC_CMD_RESET_LINK_STATS: - rep_tlv_buf = tipc_link_cmd_reset_stats(net, req_tlv_area, - req_tlv_space); - break; case TIPC_CMD_SHOW_NAME_TABLE: rep_tlv_buf = tipc_nametbl_get(net, req_tlv_area, req_tlv_space); diff --git a/net/tipc/link.c b/net/tipc/link.c index ec136b5cc339..dfe6f4d0b402 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -1969,39 +1969,6 @@ static void link_reset_statistics(struct tipc_link *l_ptr) l_ptr->stats.recv_info = l_ptr->next_in_no; } -struct sk_buff *tipc_link_cmd_reset_stats(struct net *net, - const void *req_tlv_area, - int req_tlv_space) -{ - char *link_name; - struct tipc_link *l_ptr; - struct tipc_node *node; - unsigned int bearer_id; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME)) - return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - link_name = (char *)TLV_DATA(req_tlv_area); - if (!strcmp(link_name, tipc_bclink_name)) { - if (tipc_bclink_reset_stats(net)) - return tipc_cfg_reply_error_string("link not found"); - return tipc_cfg_reply_none(); - } - node = tipc_link_find_owner(net, link_name, &bearer_id); - if (!node) - return tipc_cfg_reply_error_string("link not found"); - - tipc_node_lock(node); - l_ptr = node->links[bearer_id]; - if (!l_ptr) { - tipc_node_unlock(node); - return tipc_cfg_reply_error_string("link not found"); - } - link_reset_statistics(l_ptr); - tipc_node_unlock(node); - return tipc_cfg_reply_none(); -} - static void link_print(struct tipc_link *l_ptr, const char *str) { struct tipc_net *tn = net_generic(l_ptr->owner->net, tipc_net_id); @@ -2424,7 +2391,7 @@ int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info) struct tipc_link *link; struct tipc_node *node; struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1]; - struct net *net = genl_info_net(info); + struct net *net = sock_net(skb->sk); if (!info->attrs[TIPC_NLA_LINK]) return -EINVAL; diff --git a/net/tipc/link.h b/net/tipc/link.h index 6eb9d606063b..7aeb52092bf3 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -215,9 +215,6 @@ void tipc_link_reset_fragments(struct tipc_link *l_ptr); int tipc_link_is_up(struct tipc_link *l_ptr); int tipc_link_is_active(struct tipc_link *l_ptr); void tipc_link_purge_queues(struct tipc_link *l_ptr); -struct sk_buff *tipc_link_cmd_reset_stats(struct net *net, - const void *req_tlv_area, - int req_tlv_space); void tipc_link_reset_all(struct tipc_node *node); void tipc_link_reset(struct tipc_link *l_ptr); void tipc_link_reset_list(struct net *net, unsigned int bearer_id); diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 056532b41e7e..02461233b6d8 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -606,6 +606,26 @@ static int tipc_nl_compat_link_set(struct sk_buff *skb, return 0; } +static int tipc_nl_compat_link_reset_stats(struct sk_buff *skb, + struct tipc_nl_compat_msg *msg) +{ + char *name; + struct nlattr *link; + + name = (char *)TLV_DATA(msg->req); + + link = nla_nest_start(skb, TIPC_NLA_LINK); + if (!link) + return -EMSGSIZE; + + if (nla_put_string(skb, TIPC_NLA_LINK_NAME, name)) + return -EMSGSIZE; + + nla_nest_end(skb, link); + + return 0; +} + static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) { struct tipc_nl_compat_cmd_dump dump; @@ -650,6 +670,11 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) doit.doit = tipc_nl_link_set; doit.transcode = tipc_nl_compat_link_set; return tipc_nl_compat_doit(&doit, msg); + case TIPC_CMD_RESET_LINK_STATS: + msg->req_type = TIPC_TLV_LINK_NAME; + doit.doit = tipc_nl_link_reset_stats; + doit.transcode = tipc_nl_compat_link_reset_stats; + return tipc_nl_compat_doit(&doit, msg); } return -EOPNOTSUPP; @@ -754,6 +779,7 @@ static int tipc_nl_compat_tmp_wrap(struct sk_buff *skb, struct genl_info *info) case TIPC_CMD_SET_LINK_TOL: case TIPC_CMD_SET_LINK_PRI: case TIPC_CMD_SET_LINK_WINDOW: + case TIPC_CMD_RESET_LINK_STATS: return tipc_nl_compat_recv(skb, info); } From 44a8ae94fd5525aa06a8c71cb52efbc418fb8b7c Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:10 +0100 Subject: [PATCH 08/17] tipc: convert legacy nl name table dump to nl compat Add functionality for printing a dump header and convert TIPC_CMD_SHOW_NAME_TABLE to compat dumpit. Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/config.c | 4 - net/tipc/name_table.c | 184 -------------------------------------- net/tipc/name_table.h | 2 - net/tipc/netlink_compat.c | 101 +++++++++++++++++++++ 4 files changed, 101 insertions(+), 190 deletions(-) diff --git a/net/tipc/config.c b/net/tipc/config.c index 11c16d191fa2..7b053fcc4b87 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -209,10 +209,6 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, rep_tlv_buf = tipc_node_get_nodes(net, req_tlv_area, req_tlv_space); break; - case TIPC_CMD_SHOW_NAME_TABLE: - rep_tlv_buf = tipc_nametbl_get(net, req_tlv_area, - req_tlv_space); - break; case TIPC_CMD_GET_MEDIA_NAMES: rep_tlv_buf = tipc_media_get_names(); break; diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 2251912264a2..c8eaa2afe875 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -773,190 +773,6 @@ void tipc_nametbl_unsubscribe(struct tipc_subscription *s) spin_unlock_bh(&tn->nametbl_lock); } -/** - * subseq_list - print specified sub-sequence contents into the given buffer - */ -static int subseq_list(struct sub_seq *sseq, char *buf, int len, u32 depth, - u32 index) -{ - char portIdStr[27]; - const char *scope_str[] = {"", " zone", " cluster", " node"}; - struct publication *publ; - struct name_info *info; - int ret; - - ret = tipc_snprintf(buf, len, "%-10u %-10u ", sseq->lower, sseq->upper); - - if (depth == 2) { - ret += tipc_snprintf(buf - ret, len + ret, "\n"); - return ret; - } - - info = sseq->info; - - list_for_each_entry(publ, &info->zone_list, zone_list) { - sprintf(portIdStr, "<%u.%u.%u:%u>", - tipc_zone(publ->node), tipc_cluster(publ->node), - tipc_node(publ->node), publ->ref); - ret += tipc_snprintf(buf + ret, len - ret, "%-26s ", portIdStr); - if (depth > 3) { - ret += tipc_snprintf(buf + ret, len - ret, "%-10u %s", - publ->key, scope_str[publ->scope]); - } - if (!list_is_last(&publ->zone_list, &info->zone_list)) - ret += tipc_snprintf(buf + ret, len - ret, - "\n%33s", " "); - } - - ret += tipc_snprintf(buf + ret, len - ret, "\n"); - return ret; -} - -/** - * nameseq_list - print specified name sequence contents into the given buffer - */ -static int nameseq_list(struct name_seq *seq, char *buf, int len, u32 depth, - u32 type, u32 lowbound, u32 upbound, u32 index) -{ - struct sub_seq *sseq; - char typearea[11]; - int ret = 0; - - if (seq->first_free == 0) - return 0; - - sprintf(typearea, "%-10u", seq->type); - - if (depth == 1) { - ret += tipc_snprintf(buf, len, "%s\n", typearea); - return ret; - } - - for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) { - if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) { - ret += tipc_snprintf(buf + ret, len - ret, "%s ", - typearea); - spin_lock_bh(&seq->lock); - ret += subseq_list(sseq, buf + ret, len - ret, - depth, index); - spin_unlock_bh(&seq->lock); - sprintf(typearea, "%10s", " "); - } - } - return ret; -} - -/** - * nametbl_header - print name table header into the given buffer - */ -static int nametbl_header(char *buf, int len, u32 depth) -{ - const char *header[] = { - "Type ", - "Lower Upper ", - "Port Identity ", - "Publication Scope" - }; - - int i; - int ret = 0; - - if (depth > 4) - depth = 4; - for (i = 0; i < depth; i++) - ret += tipc_snprintf(buf + ret, len - ret, header[i]); - ret += tipc_snprintf(buf + ret, len - ret, "\n"); - return ret; -} - -/** - * nametbl_list - print specified name table contents into the given buffer - */ -static int nametbl_list(struct net *net, char *buf, int len, u32 depth_info, - u32 type, u32 lowbound, u32 upbound) -{ - struct tipc_net *tn = net_generic(net, tipc_net_id); - struct hlist_head *seq_head; - struct name_seq *seq; - int all_types; - int ret = 0; - u32 depth; - u32 i; - - all_types = (depth_info & TIPC_NTQ_ALLTYPES); - depth = (depth_info & ~TIPC_NTQ_ALLTYPES); - - if (depth == 0) - return 0; - - if (all_types) { - /* display all entries in name table to specified depth */ - ret += nametbl_header(buf, len, depth); - lowbound = 0; - upbound = ~0; - for (i = 0; i < TIPC_NAMETBL_SIZE; i++) { - seq_head = &tn->nametbl->seq_hlist[i]; - hlist_for_each_entry_rcu(seq, seq_head, ns_list) { - ret += nameseq_list(seq, buf + ret, len - ret, - depth, seq->type, - lowbound, upbound, i); - } - } - } else { - /* display only the sequence that matches the specified type */ - if (upbound < lowbound) { - ret += tipc_snprintf(buf + ret, len - ret, - "invalid name sequence specified\n"); - return ret; - } - ret += nametbl_header(buf + ret, len - ret, depth); - i = hash(type); - seq_head = &tn->nametbl->seq_hlist[i]; - hlist_for_each_entry_rcu(seq, seq_head, ns_list) { - if (seq->type == type) { - ret += nameseq_list(seq, buf + ret, len - ret, - depth, type, - lowbound, upbound, i); - break; - } - } - } - return ret; -} - -struct sk_buff *tipc_nametbl_get(struct net *net, const void *req_tlv_area, - int req_tlv_space) -{ - struct sk_buff *buf; - struct tipc_name_table_query *argv; - struct tlv_desc *rep_tlv; - char *pb; - int pb_len; - int str_len; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NAME_TBL_QUERY)) - return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); - if (!buf) - return NULL; - - rep_tlv = (struct tlv_desc *)buf->data; - pb = TLV_DATA(rep_tlv); - pb_len = ULTRA_STRING_MAX_LEN; - argv = (struct tipc_name_table_query *)TLV_DATA(req_tlv_area); - rcu_read_lock(); - str_len = nametbl_list(net, pb, pb_len, ntohl(argv->depth), - ntohl(argv->type), - ntohl(argv->lowbound), ntohl(argv->upbound)); - rcu_read_unlock(); - str_len += 1; /* for "\0" */ - skb_put(buf, TLV_SPACE(str_len)); - TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); - - return buf; -} - int tipc_nametbl_init(struct net *net) { struct tipc_net *tn = net_generic(net, tipc_net_id); 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 { int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb); -struct sk_buff *tipc_nametbl_get(struct net *net, const void *req_tlv_area, - int req_tlv_space); u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *node); int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper, u32 limit, struct tipc_plist *dports); diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 02461233b6d8..40c24ea31231 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -35,6 +35,7 @@ #include "config.h" #include "bearer.h" #include "link.h" +#include "name_table.h" #include #include @@ -58,6 +59,7 @@ struct tipc_nl_compat_msg { }; struct tipc_nl_compat_cmd_dump { + int (*header)(struct tipc_nl_compat_msg *); int (*dumpit)(struct sk_buff *, struct netlink_callback *); int (*format)(struct tipc_nl_compat_msg *msg, struct nlattr **attrs); }; @@ -246,6 +248,9 @@ static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, if (msg->rep_type) tipc_tlv_init(msg->rep, msg->rep_type); + if (cmd->header) + (*cmd->header)(msg); + arg = nlmsg_new(0, GFP_KERNEL); if (!arg) { kfree_skb(msg->rep); @@ -626,6 +631,93 @@ static int tipc_nl_compat_link_reset_stats(struct sk_buff *skb, return 0; } +static int tipc_nl_compat_name_table_dump_header(struct tipc_nl_compat_msg *msg) +{ + int i; + u32 depth; + struct tipc_name_table_query *ntq; + static const char * const header[] = { + "Type ", + "Lower Upper ", + "Port Identity ", + "Publication Scope" + }; + + ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req); + + depth = ntohl(ntq->depth); + + if (depth > 4) + depth = 4; + for (i = 0; i < depth; i++) + tipc_tlv_sprintf(msg->rep, header[i]); + tipc_tlv_sprintf(msg->rep, "\n"); + + return 0; +} + +static int tipc_nl_compat_name_table_dump(struct tipc_nl_compat_msg *msg, + struct nlattr **attrs) +{ + char port_str[27]; + struct tipc_name_table_query *ntq; + struct nlattr *nt[TIPC_NLA_NAME_TABLE_MAX + 1]; + struct nlattr *publ[TIPC_NLA_PUBL_MAX + 1]; + u32 node, depth, type, lowbound, upbound; + static const char * const scope_str[] = {"", " zone", " cluster", + " node"}; + + nla_parse_nested(nt, TIPC_NLA_NAME_TABLE_MAX, + attrs[TIPC_NLA_NAME_TABLE], NULL); + + nla_parse_nested(publ, TIPC_NLA_PUBL_MAX, nt[TIPC_NLA_NAME_TABLE_PUBL], + NULL); + + ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req); + + depth = ntohl(ntq->depth); + type = ntohl(ntq->type); + lowbound = ntohl(ntq->lowbound); + upbound = ntohl(ntq->upbound); + + if (!(depth & TIPC_NTQ_ALLTYPES) && + (type != nla_get_u32(publ[TIPC_NLA_PUBL_TYPE]))) + return 0; + if (lowbound && (lowbound > nla_get_u32(publ[TIPC_NLA_PUBL_UPPER]))) + return 0; + if (upbound && (upbound < nla_get_u32(publ[TIPC_NLA_PUBL_LOWER]))) + return 0; + + tipc_tlv_sprintf(msg->rep, "%-10u ", + nla_get_u32(publ[TIPC_NLA_PUBL_TYPE])); + + if (depth == 1) + goto out; + + tipc_tlv_sprintf(msg->rep, "%-10u %-10u ", + nla_get_u32(publ[TIPC_NLA_PUBL_LOWER]), + nla_get_u32(publ[TIPC_NLA_PUBL_UPPER])); + + if (depth == 2) + goto out; + + node = nla_get_u32(publ[TIPC_NLA_PUBL_NODE]); + sprintf(port_str, "<%u.%u.%u:%u>", tipc_zone(node), tipc_cluster(node), + tipc_node(node), nla_get_u32(publ[TIPC_NLA_PUBL_REF])); + tipc_tlv_sprintf(msg->rep, "%-26s ", port_str); + + if (depth == 3) + goto out; + + tipc_tlv_sprintf(msg->rep, "%-10u %s", + nla_get_u32(publ[TIPC_NLA_PUBL_REF]), + scope_str[nla_get_u32(publ[TIPC_NLA_PUBL_SCOPE])]); +out: + tipc_tlv_sprintf(msg->rep, "\n"); + + return 0; +} + static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) { struct tipc_nl_compat_cmd_dump dump; @@ -675,6 +767,14 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) doit.doit = tipc_nl_link_reset_stats; doit.transcode = tipc_nl_compat_link_reset_stats; return tipc_nl_compat_doit(&doit, msg); + case TIPC_CMD_SHOW_NAME_TABLE: + msg->req_type = TIPC_TLV_NAME_TBL_QUERY; + msg->rep_size = ULTRA_STRING_MAX_LEN; + msg->rep_type = TIPC_TLV_ULTRA_STRING; + dump.header = tipc_nl_compat_name_table_dump_header; + dump.dumpit = tipc_nl_name_table_dump; + dump.format = tipc_nl_compat_name_table_dump; + return tipc_nl_compat_dumpit(&dump, msg); } return -EOPNOTSUPP; @@ -780,6 +880,7 @@ static int tipc_nl_compat_tmp_wrap(struct sk_buff *skb, struct genl_info *info) case TIPC_CMD_SET_LINK_PRI: case TIPC_CMD_SET_LINK_WINDOW: case TIPC_CMD_RESET_LINK_STATS: + case TIPC_CMD_SHOW_NAME_TABLE: return tipc_nl_compat_recv(skb, info); } From 487d2a3a1326d339ce273ffbcd03247f2b7b052e Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:11 +0100 Subject: [PATCH 09/17] tipc: convert legacy nl socket dump to nl compat Convert socket (port) listing to compat dumpit call. If a socket (port) has publications a second dumpit call is issued to collect them and format then into the legacy buffer before continuing to process the sockets (ports). Command converted in this patch: TIPC_CMD_SHOW_PORTS Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/config.c | 3 -- net/tipc/netlink_compat.c | 111 ++++++++++++++++++++++++++++++++++++++ net/tipc/socket.c | 85 ----------------------------- net/tipc/socket.h | 1 - 4 files changed, 111 insertions(+), 89 deletions(-) diff --git a/net/tipc/config.c b/net/tipc/config.c index 7b053fcc4b87..6e4c215879c8 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -212,9 +212,6 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, case TIPC_CMD_GET_MEDIA_NAMES: rep_tlv_buf = tipc_media_get_names(); break; - case TIPC_CMD_SHOW_PORTS: - rep_tlv_buf = tipc_sk_socks_show(net); - break; case TIPC_CMD_SHOW_STATS: rep_tlv_buf = tipc_show_stats(); break; diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 40c24ea31231..48e15a4a36d8 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -36,6 +36,7 @@ #include "bearer.h" #include "link.h" #include "name_table.h" +#include "socket.h" #include #include @@ -718,6 +719,109 @@ out: return 0; } +static int __tipc_nl_compat_publ_dump(struct tipc_nl_compat_msg *msg, + struct nlattr **attrs) +{ + u32 type, lower, upper; + struct nlattr *publ[TIPC_NLA_PUBL_MAX + 1]; + + nla_parse_nested(publ, TIPC_NLA_PUBL_MAX, attrs[TIPC_NLA_PUBL], NULL); + + type = nla_get_u32(publ[TIPC_NLA_PUBL_TYPE]); + lower = nla_get_u32(publ[TIPC_NLA_PUBL_LOWER]); + upper = nla_get_u32(publ[TIPC_NLA_PUBL_UPPER]); + + if (lower == upper) + tipc_tlv_sprintf(msg->rep, " {%u,%u}", type, lower); + else + tipc_tlv_sprintf(msg->rep, " {%u,%u,%u}", type, lower, upper); + + return 0; +} + +static int tipc_nl_compat_publ_dump(struct tipc_nl_compat_msg *msg, u32 sock) +{ + int err; + void *hdr; + struct nlattr *nest; + struct sk_buff *args; + struct tipc_nl_compat_cmd_dump dump; + + args = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!args) + return -ENOMEM; + + hdr = genlmsg_put(args, 0, 0, &tipc_genl_family, NLM_F_MULTI, + TIPC_NL_PUBL_GET); + + nest = nla_nest_start(args, TIPC_NLA_SOCK); + if (!nest) { + kfree_skb(args); + return -EMSGSIZE; + } + + if (nla_put_u32(args, TIPC_NLA_SOCK_REF, sock)) { + kfree_skb(args); + return -EMSGSIZE; + } + + nla_nest_end(args, nest); + genlmsg_end(args, hdr); + + dump.dumpit = tipc_nl_publ_dump; + dump.format = __tipc_nl_compat_publ_dump; + + err = __tipc_nl_compat_dumpit(&dump, msg, args); + + kfree_skb(args); + + return err; +} + +static int tipc_nl_compat_sk_dump(struct tipc_nl_compat_msg *msg, + struct nlattr **attrs) +{ + int err; + u32 sock_ref; + struct nlattr *sock[TIPC_NLA_SOCK_MAX + 1]; + + nla_parse_nested(sock, TIPC_NLA_SOCK_MAX, attrs[TIPC_NLA_SOCK], NULL); + + sock_ref = nla_get_u32(sock[TIPC_NLA_SOCK_REF]); + tipc_tlv_sprintf(msg->rep, "%u:", sock_ref); + + if (sock[TIPC_NLA_SOCK_CON]) { + u32 node; + struct nlattr *con[TIPC_NLA_CON_MAX + 1]; + + nla_parse_nested(con, TIPC_NLA_CON_MAX, sock[TIPC_NLA_SOCK_CON], + NULL); + + node = nla_get_u32(con[TIPC_NLA_CON_NODE]); + tipc_tlv_sprintf(msg->rep, " connected to <%u.%u.%u:%u>", + tipc_zone(node), + tipc_cluster(node), + tipc_node(node), + nla_get_u32(con[TIPC_NLA_CON_SOCK])); + + if (con[TIPC_NLA_CON_FLAG]) + tipc_tlv_sprintf(msg->rep, " via {%u,%u}\n", + nla_get_u32(con[TIPC_NLA_CON_TYPE]), + nla_get_u32(con[TIPC_NLA_CON_INST])); + else + tipc_tlv_sprintf(msg->rep, "\n"); + } else if (sock[TIPC_NLA_SOCK_HAS_PUBL]) { + tipc_tlv_sprintf(msg->rep, " bound to"); + + err = tipc_nl_compat_publ_dump(msg, sock_ref); + if (err) + return err; + } + tipc_tlv_sprintf(msg->rep, "\n"); + + return 0; +} + static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) { struct tipc_nl_compat_cmd_dump dump; @@ -775,6 +879,12 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) dump.dumpit = tipc_nl_name_table_dump; dump.format = tipc_nl_compat_name_table_dump; return tipc_nl_compat_dumpit(&dump, msg); + case TIPC_CMD_SHOW_PORTS: + msg->rep_size = ULTRA_STRING_MAX_LEN; + msg->rep_type = TIPC_TLV_ULTRA_STRING; + dump.dumpit = tipc_nl_sk_dump; + dump.format = tipc_nl_compat_sk_dump; + return tipc_nl_compat_dumpit(&dump, msg); } return -EOPNOTSUPP; @@ -881,6 +991,7 @@ static int tipc_nl_compat_tmp_wrap(struct sk_buff *skb, struct genl_info *info) case TIPC_CMD_SET_LINK_WINDOW: case TIPC_CMD_RESET_LINK_STATS: case TIPC_CMD_SHOW_NAME_TABLE: + case TIPC_CMD_SHOW_PORTS: return tipc_nl_compat_recv(skb, info); } diff --git a/net/tipc/socket.c b/net/tipc/socket.c index d76c171f7b7e..e77d738bb771 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -2281,91 +2281,6 @@ static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope, return rc; } -static int tipc_sk_show(struct tipc_sock *tsk, char *buf, - int len, int full_id) -{ - struct net *net = sock_net(&tsk->sk); - struct tipc_net *tn = net_generic(net, tipc_net_id); - struct publication *publ; - int ret; - - if (full_id) - ret = tipc_snprintf(buf, len, "<%u.%u.%u:%u>:", - tipc_zone(tn->own_addr), - tipc_cluster(tn->own_addr), - tipc_node(tn->own_addr), tsk->portid); - else - ret = tipc_snprintf(buf, len, "%-10u:", tsk->portid); - - if (tsk->connected) { - u32 dport = tsk_peer_port(tsk); - u32 destnode = tsk_peer_node(tsk); - - ret += tipc_snprintf(buf + ret, len - ret, - " connected to <%u.%u.%u:%u>", - tipc_zone(destnode), - tipc_cluster(destnode), - tipc_node(destnode), dport); - if (tsk->conn_type != 0) - ret += tipc_snprintf(buf + ret, len - ret, - " via {%u,%u}", tsk->conn_type, - tsk->conn_instance); - } else if (tsk->published) { - ret += tipc_snprintf(buf + ret, len - ret, " bound to"); - list_for_each_entry(publ, &tsk->publications, pport_list) { - if (publ->lower == publ->upper) - ret += tipc_snprintf(buf + ret, len - ret, - " {%u,%u}", publ->type, - publ->lower); - else - ret += tipc_snprintf(buf + ret, len - ret, - " {%u,%u,%u}", publ->type, - publ->lower, publ->upper); - } - } - ret += tipc_snprintf(buf + ret, len - ret, "\n"); - return ret; -} - -struct sk_buff *tipc_sk_socks_show(struct net *net) -{ - struct tipc_net *tn = net_generic(net, tipc_net_id); - const struct bucket_table *tbl; - struct rhash_head *pos; - struct sk_buff *buf; - struct tlv_desc *rep_tlv; - char *pb; - int pb_len; - struct tipc_sock *tsk; - int str_len = 0; - int i; - - buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); - if (!buf) - return NULL; - rep_tlv = (struct tlv_desc *)buf->data; - pb = TLV_DATA(rep_tlv); - pb_len = ULTRA_STRING_MAX_LEN; - - rcu_read_lock(); - tbl = rht_dereference_rcu((&tn->sk_rht)->tbl, &tn->sk_rht); - for (i = 0; i < tbl->size; i++) { - rht_for_each_entry_rcu(tsk, pos, tbl, i, node) { - spin_lock_bh(&tsk->sk.sk_lock.slock); - str_len += tipc_sk_show(tsk, pb + str_len, - pb_len - str_len, 0); - spin_unlock_bh(&tsk->sk.sk_lock.slock); - } - } - rcu_read_unlock(); - - str_len += 1; /* for "\0" */ - skb_put(buf, TLV_SPACE(str_len)); - TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); - - return buf; -} - /* tipc_sk_reinit: set non-zero address in all existing sockets * when we go from standalone to network mode. */ 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); int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, int flags); int tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq); -struct sk_buff *tipc_sk_socks_show(struct net *net); void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, struct sk_buff_head *inputq); void tipc_sk_reinit(struct net *net); From 5bfc335a637ad4aecededb67b0075aae72a6dbb3 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:12 +0100 Subject: [PATCH 10/17] tipc: convert legacy nl media dump to nl compat Convert TIPC_CMD_GET_MEDIA_NAMES to compat dumpit. Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/bearer.c | 20 -------------------- net/tipc/bearer.h | 1 - net/tipc/config.c | 3 --- net/tipc/netlink_compat.c | 19 +++++++++++++++++++ 4 files changed, 19 insertions(+), 24 deletions(-) diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index de1c800ef806..c7e3b5d3baa9 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -123,26 +123,6 @@ void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a) } } -/** - * tipc_media_get_names - record names of registered media in buffer - */ -struct sk_buff *tipc_media_get_names(void) -{ - struct sk_buff *buf; - int i; - - buf = tipc_cfg_reply_alloc(MAX_MEDIA * TLV_SPACE(TIPC_MAX_MEDIA_NAME)); - if (!buf) - return NULL; - - for (i = 0; media_info_array[i] != NULL; i++) { - tipc_cfg_append_tlv(buf, TIPC_TLV_MEDIA_NAME, - media_info_array[i]->name, - strlen(media_info_array[i]->name) + 1); - } - return buf; -} - /** * bearer_name_validate - validate & (optionally) deconstruct bearer name * @name: ptr to bearer name string diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index 06f25d144871..6b17795ff8bc 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -196,7 +196,6 @@ int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info); int tipc_media_set_priority(const char *name, u32 new_value); int tipc_media_set_window(const char *name, u32 new_value); void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a); -struct sk_buff *tipc_media_get_names(void); int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b); void tipc_disable_l2_media(struct tipc_bearer *b); int tipc_l2_send_msg(struct net *net, struct sk_buff *buf, diff --git a/net/tipc/config.c b/net/tipc/config.c index 6e4c215879c8..df410823e889 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -209,9 +209,6 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, rep_tlv_buf = tipc_node_get_nodes(net, req_tlv_area, req_tlv_space); break; - case TIPC_CMD_GET_MEDIA_NAMES: - rep_tlv_buf = tipc_media_get_names(); - break; case TIPC_CMD_SHOW_STATS: rep_tlv_buf = tipc_show_stats(); break; diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 48e15a4a36d8..d23075efaa76 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -822,6 +822,19 @@ static int tipc_nl_compat_sk_dump(struct tipc_nl_compat_msg *msg, return 0; } +static int tipc_nl_compat_media_dump(struct tipc_nl_compat_msg *msg, + struct nlattr **attrs) +{ + struct nlattr *media[TIPC_NLA_MEDIA_MAX + 1]; + + nla_parse_nested(media, TIPC_NLA_MEDIA_MAX, attrs[TIPC_NLA_MEDIA], + NULL); + + return tipc_add_tlv(msg->rep, TIPC_TLV_MEDIA_NAME, + nla_data(media[TIPC_NLA_MEDIA_NAME]), + nla_len(media[TIPC_NLA_MEDIA_NAME])); +} + static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) { struct tipc_nl_compat_cmd_dump dump; @@ -885,6 +898,11 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) dump.dumpit = tipc_nl_sk_dump; dump.format = tipc_nl_compat_sk_dump; return tipc_nl_compat_dumpit(&dump, msg); + case TIPC_CMD_GET_MEDIA_NAMES: + msg->rep_size = MAX_MEDIA * TLV_SPACE(TIPC_MAX_MEDIA_NAME); + dump.dumpit = tipc_nl_media_dump; + dump.format = tipc_nl_compat_media_dump; + return tipc_nl_compat_dumpit(&dump, msg); } return -EOPNOTSUPP; @@ -992,6 +1010,7 @@ static int tipc_nl_compat_tmp_wrap(struct sk_buff *skb, struct genl_info *info) case TIPC_CMD_RESET_LINK_STATS: case TIPC_CMD_SHOW_NAME_TABLE: case TIPC_CMD_SHOW_PORTS: + case TIPC_CMD_GET_MEDIA_NAMES: return tipc_nl_compat_recv(skb, info); } From 4b28cb581dd0df8d8ff19151f39683f641e576ba Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:13 +0100 Subject: [PATCH 11/17] tipc: convert legacy nl node dump to nl compat Convert TIPC_CMD_GET_NODES to compat dumpit and remove global node counter solely used by the legacy API. Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/config.c | 4 --- net/tipc/netlink_compat.c | 22 ++++++++++++++++ net/tipc/node.c | 54 --------------------------------------- net/tipc/node.h | 2 -- 4 files changed, 22 insertions(+), 60 deletions(-) diff --git a/net/tipc/config.c b/net/tipc/config.c index df410823e889..74babd75c07d 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -205,10 +205,6 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, case TIPC_CMD_NOOP: rep_tlv_buf = tipc_cfg_reply_none(); break; - case TIPC_CMD_GET_NODES: - rep_tlv_buf = tipc_node_get_nodes(net, req_tlv_area, - req_tlv_space); - break; case TIPC_CMD_SHOW_STATS: rep_tlv_buf = tipc_show_stats(); break; diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index d23075efaa76..0dc448e77e13 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -37,6 +37,7 @@ #include "link.h" #include "name_table.h" #include "socket.h" +#include "node.h" #include #include @@ -835,6 +836,21 @@ static int tipc_nl_compat_media_dump(struct tipc_nl_compat_msg *msg, nla_len(media[TIPC_NLA_MEDIA_NAME])); } +static int tipc_nl_compat_node_dump(struct tipc_nl_compat_msg *msg, + struct nlattr **attrs) +{ + struct tipc_node_info node_info; + struct nlattr *node[TIPC_NLA_NODE_MAX + 1]; + + nla_parse_nested(node, TIPC_NLA_NODE_MAX, attrs[TIPC_NLA_NODE], NULL); + + node_info.addr = htonl(nla_get_u32(node[TIPC_NLA_NODE_ADDR])); + node_info.up = htonl(nla_get_flag(node[TIPC_NLA_NODE_UP])); + + return tipc_add_tlv(msg->rep, TIPC_TLV_NODE_INFO, &node_info, + sizeof(node_info)); +} + static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) { struct tipc_nl_compat_cmd_dump dump; @@ -903,6 +919,11 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) dump.dumpit = tipc_nl_media_dump; dump.format = tipc_nl_compat_media_dump; return tipc_nl_compat_dumpit(&dump, msg); + case TIPC_CMD_GET_NODES: + msg->rep_size = ULTRA_STRING_MAX_LEN; + dump.dumpit = tipc_nl_node_dump; + dump.format = tipc_nl_compat_node_dump; + return tipc_nl_compat_dumpit(&dump, msg); } return -EOPNOTSUPP; @@ -1011,6 +1032,7 @@ static int tipc_nl_compat_tmp_wrap(struct sk_buff *skb, struct genl_info *info) case TIPC_CMD_SHOW_NAME_TABLE: case TIPC_CMD_SHOW_PORTS: case TIPC_CMD_GET_MEDIA_NAMES: + case TIPC_CMD_GET_NODES: return tipc_nl_compat_recv(skb, info); } diff --git a/net/tipc/node.c b/net/tipc/node.c index 46b87f77d342..ddaa2bbaa35d 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -120,7 +120,6 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr) list_add_tail_rcu(&n_ptr->list, &temp_node->list); n_ptr->action_flags = TIPC_WAIT_PEER_LINKS_DOWN; n_ptr->signature = INVALID_NODE_SIG; - tn->num_nodes++; exit: spin_unlock_bh(&tn->node_list_lock); return n_ptr; @@ -131,8 +130,6 @@ static void tipc_node_delete(struct tipc_net *tn, struct tipc_node *n_ptr) list_del_rcu(&n_ptr->list); hlist_del_rcu(&n_ptr->hash); kfree_rcu(n_ptr, rcu); - - tn->num_nodes--; } void tipc_node_stop(struct net *net) @@ -407,57 +404,6 @@ static void node_lost_contact(struct tipc_node *n_ptr) } } -struct sk_buff *tipc_node_get_nodes(struct net *net, const void *req_tlv_area, - int req_tlv_space) -{ - struct tipc_net *tn = net_generic(net, tipc_net_id); - u32 domain; - struct sk_buff *buf; - struct tipc_node *n_ptr; - struct tipc_node_info node_info; - u32 payload_size; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) - return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - domain = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); - if (!tipc_addr_domain_valid(domain)) - return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE - " (network address)"); - - spin_lock_bh(&tn->node_list_lock); - if (!tn->num_nodes) { - spin_unlock_bh(&tn->node_list_lock); - return tipc_cfg_reply_none(); - } - - /* For now, get space for all other nodes */ - payload_size = TLV_SPACE(sizeof(node_info)) * tn->num_nodes; - if (payload_size > 32768u) { - spin_unlock_bh(&tn->node_list_lock); - return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (too many nodes)"); - } - spin_unlock_bh(&tn->node_list_lock); - - buf = tipc_cfg_reply_alloc(payload_size); - if (!buf) - return NULL; - - /* Add TLVs for all nodes in scope */ - rcu_read_lock(); - list_for_each_entry_rcu(n_ptr, &tn->node_list, list) { - if (!tipc_in_scope(domain, n_ptr->addr)) - continue; - node_info.addr = htonl(n_ptr->addr); - node_info.up = htonl(tipc_node_is_up(n_ptr)); - tipc_cfg_append_tlv(buf, TIPC_TLV_NODE_INFO, - &node_info, sizeof(node_info)); - } - rcu_read_unlock(); - return buf; -} - /** * tipc_node_get_linkname - get the name of a link * diff --git a/net/tipc/node.h b/net/tipc/node.h index 59dafee61aa0..3d18c66b7f78 100644 --- a/net/tipc/node.h +++ b/net/tipc/node.h @@ -142,8 +142,6 @@ void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr); void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr); int tipc_node_active_links(struct tipc_node *n_ptr); int tipc_node_is_up(struct tipc_node *n_ptr); -struct sk_buff *tipc_node_get_nodes(struct net *net, const void *req_tlv_area, - int req_tlv_space); int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 node, char *linkname, size_t len); void tipc_node_unlock(struct tipc_node *node); From d7cc75d3cb6beac88a2bd041a7700154b73a989d Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:14 +0100 Subject: [PATCH 12/17] tipc: convert legacy nl node addr set to nl compat Convert TIPC_CMD_SET_NODE_ADDR to compat doit. Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/config.c | 26 -------------------------- net/tipc/net.c | 2 +- net/tipc/netlink_compat.c | 26 ++++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/net/tipc/config.c b/net/tipc/config.c index 74babd75c07d..2a2d05be8a27 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -134,29 +134,6 @@ static struct sk_buff *tipc_show_stats(void) return buf; } -static struct sk_buff *cfg_set_own_addr(struct net *net) -{ - struct tipc_net *tn = net_generic(net, tipc_net_id); - u32 addr; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) - return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - addr = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); - if (addr == tn->own_addr) - return tipc_cfg_reply_none(); - if (!tipc_addr_node_valid(addr)) - return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE - " (node address)"); - if (tn->own_addr) - return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (cannot change node address once assigned)"); - if (!tipc_net_start(net, addr)) - return tipc_cfg_reply_none(); - - return tipc_cfg_reply_error_string("cannot change to network mode"); -} - static struct sk_buff *cfg_set_netid(struct net *net) { struct tipc_net *tn = net_generic(net, tipc_net_id); @@ -208,9 +185,6 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, case TIPC_CMD_SHOW_STATS: rep_tlv_buf = tipc_show_stats(); break; - case TIPC_CMD_SET_NODE_ADDR: - rep_tlv_buf = cfg_set_own_addr(net); - break; case TIPC_CMD_SET_NETID: rep_tlv_buf = cfg_set_netid(net); break; diff --git a/net/tipc/net.c b/net/tipc/net.c index 8b0fb0966628..e4028f927c8a 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c @@ -208,7 +208,7 @@ out: int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info) { - struct net *net = genl_info_net(info); + struct net *net = sock_net(skb->sk); struct tipc_net *tn = net_generic(net, tipc_net_id); struct nlattr *attrs[TIPC_NLA_NET_MAX + 1]; int err; diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 0dc448e77e13..aa0e3256ae93 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -851,6 +851,26 @@ static int tipc_nl_compat_node_dump(struct tipc_nl_compat_msg *msg, sizeof(node_info)); } +static int tipc_nl_compat_net_set(struct sk_buff *skb, + struct tipc_nl_compat_msg *msg) +{ + u32 val; + struct nlattr *net; + + val = ntohl(*(__be32 *)TLV_DATA(msg->req)); + + net = nla_nest_start(skb, TIPC_NLA_NET); + if (!net) + return -EMSGSIZE; + + if (nla_put_u32(skb, TIPC_NLA_NET_ADDR, val)) + return -EMSGSIZE; + + nla_nest_end(skb, net); + + return 0; +} + static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) { struct tipc_nl_compat_cmd_dump dump; @@ -924,6 +944,11 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) dump.dumpit = tipc_nl_node_dump; dump.format = tipc_nl_compat_node_dump; return tipc_nl_compat_dumpit(&dump, msg); + case TIPC_CMD_SET_NODE_ADDR: + msg->req_type = TIPC_TLV_NET_ADDR; + doit.doit = tipc_nl_net_set; + doit.transcode = tipc_nl_compat_net_set; + return tipc_nl_compat_doit(&doit, msg); } return -EOPNOTSUPP; @@ -1033,6 +1058,7 @@ static int tipc_nl_compat_tmp_wrap(struct sk_buff *skb, struct genl_info *info) case TIPC_CMD_SHOW_PORTS: case TIPC_CMD_GET_MEDIA_NAMES: case TIPC_CMD_GET_NODES: + case TIPC_CMD_SET_NODE_ADDR: return tipc_nl_compat_recv(skb, info); } From 964f9501c1910c0835eee3cf870ba5aa44db1241 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:15 +0100 Subject: [PATCH 13/17] tipc: convert legacy nl net id set to nl compat Convert TIPC_CMD_SET_NETID to compat doit. Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/config.c | 23 ----------------------- net/tipc/netlink_compat.c | 17 ++++++++++++++--- 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/net/tipc/config.c b/net/tipc/config.c index 2a2d05be8a27..080cc92eedca 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -134,26 +134,6 @@ static struct sk_buff *tipc_show_stats(void) return buf; } -static struct sk_buff *cfg_set_netid(struct net *net) -{ - struct tipc_net *tn = net_generic(net, tipc_net_id); - u32 value; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) - return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); - if (value == tn->net_id) - return tipc_cfg_reply_none(); - if (value < 1 || value > 9999) - return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE - " (network id must be 1-9999)"); - if (tn->own_addr) - return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (cannot change network id once TIPC has joined a network)"); - tn->net_id = value; - return tipc_cfg_reply_none(); -} - struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, const void *request_area, int request_space, int reply_headroom) @@ -185,9 +165,6 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, case TIPC_CMD_SHOW_STATS: rep_tlv_buf = tipc_show_stats(); break; - case TIPC_CMD_SET_NETID: - rep_tlv_buf = cfg_set_netid(net); - break; case TIPC_CMD_GET_NETID: rep_tlv_buf = tipc_cfg_reply_unsigned(tn->net_id); break; diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index aa0e3256ae93..c355476a6e7c 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -38,6 +38,7 @@ #include "name_table.h" #include "socket.h" #include "node.h" +#include "net.h" #include #include @@ -863,9 +864,13 @@ static int tipc_nl_compat_net_set(struct sk_buff *skb, if (!net) return -EMSGSIZE; - if (nla_put_u32(skb, TIPC_NLA_NET_ADDR, val)) - return -EMSGSIZE; - + if (msg->cmd == TIPC_CMD_SET_NODE_ADDR) { + if (nla_put_u32(skb, TIPC_NLA_NET_ADDR, val)) + return -EMSGSIZE; + } else if (msg->cmd == TIPC_CMD_SET_NETID) { + if (nla_put_u32(skb, TIPC_NLA_NET_ID, val)) + return -EMSGSIZE; + } nla_nest_end(skb, net); return 0; @@ -949,6 +954,11 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) doit.doit = tipc_nl_net_set; doit.transcode = tipc_nl_compat_net_set; return tipc_nl_compat_doit(&doit, msg); + case TIPC_CMD_SET_NETID: + msg->req_type = TIPC_TLV_UNSIGNED; + doit.doit = tipc_nl_net_set; + doit.transcode = tipc_nl_compat_net_set; + return tipc_nl_compat_doit(&doit, msg); } return -EOPNOTSUPP; @@ -1059,6 +1069,7 @@ static int tipc_nl_compat_tmp_wrap(struct sk_buff *skb, struct genl_info *info) case TIPC_CMD_GET_MEDIA_NAMES: case TIPC_CMD_GET_NODES: case TIPC_CMD_SET_NODE_ADDR: + case TIPC_CMD_SET_NETID: return tipc_nl_compat_recv(skb, info); } From 3c26181c5b1b0b49e147bac8a8d012234f813a5e Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:16 +0100 Subject: [PATCH 14/17] tipc: convert legacy nl net id get to nl compat Convert TIPC_CMD_GET_NETID to compat dumpit. Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/config.c | 23 ----------------------- net/tipc/netlink_compat.c | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/net/tipc/config.c b/net/tipc/config.c index 080cc92eedca..019f46c0690c 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -72,25 +72,6 @@ int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type, return 1; } -static struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value) -{ - struct sk_buff *buf; - __be32 value_net; - - buf = tipc_cfg_reply_alloc(TLV_SPACE(sizeof(value))); - if (buf) { - value_net = htonl(value); - tipc_cfg_append_tlv(buf, tlv_type, &value_net, - sizeof(value_net)); - } - return buf; -} - -static struct sk_buff *tipc_cfg_reply_unsigned(u32 value) -{ - return tipc_cfg_reply_unsigned_type(TIPC_TLV_UNSIGNED, value); -} - struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string) { struct sk_buff *buf; @@ -139,7 +120,6 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, int reply_headroom) { struct sk_buff *rep_tlv_buf; - struct tipc_net *tn = net_generic(net, tipc_net_id); rtnl_lock(); @@ -165,9 +145,6 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, case TIPC_CMD_SHOW_STATS: rep_tlv_buf = tipc_show_stats(); break; - case TIPC_CMD_GET_NETID: - rep_tlv_buf = tipc_cfg_reply_unsigned(tn->net_id); - break; case TIPC_CMD_NOT_NET_ADMIN: rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN); diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index c355476a6e7c..415909054ec0 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -876,6 +876,18 @@ static int tipc_nl_compat_net_set(struct sk_buff *skb, return 0; } +static int tipc_nl_compat_net_dump(struct tipc_nl_compat_msg *msg, + struct nlattr **attrs) +{ + __be32 id; + struct nlattr *net[TIPC_NLA_NET_MAX + 1]; + + nla_parse_nested(net, TIPC_NLA_NET_MAX, attrs[TIPC_NLA_NET], NULL); + id = htonl(nla_get_u32(net[TIPC_NLA_NET_ID])); + + return tipc_add_tlv(msg->rep, TIPC_TLV_UNSIGNED, &id, sizeof(id)); +} + static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) { struct tipc_nl_compat_cmd_dump dump; @@ -959,6 +971,11 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) doit.doit = tipc_nl_net_set; doit.transcode = tipc_nl_compat_net_set; return tipc_nl_compat_doit(&doit, msg); + case TIPC_CMD_GET_NETID: + msg->rep_size = sizeof(u32); + dump.dumpit = tipc_nl_net_dump; + dump.format = tipc_nl_compat_net_dump; + return tipc_nl_compat_dumpit(&dump, msg); } return -EOPNOTSUPP; @@ -1070,6 +1087,7 @@ static int tipc_nl_compat_tmp_wrap(struct sk_buff *skb, struct genl_info *info) case TIPC_CMD_GET_NODES: case TIPC_CMD_SET_NODE_ADDR: case TIPC_CMD_SET_NETID: + case TIPC_CMD_GET_NETID: return tipc_nl_compat_recv(skb, info); } From 5a81a6377b6083fccffdfb7a21ec080b8d58475b Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:17 +0100 Subject: [PATCH 15/17] tipc: convert legacy nl stats show to nl compat Convert TIPC_CMD_SHOW_STATS to compat layer. This command does not have any counterpart in the new API, meaning it now solely exists as a function in the compat layer. Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/config.c | 35 ----------------------------------- net/tipc/netlink_compat.c | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 35 deletions(-) diff --git a/net/tipc/config.c b/net/tipc/config.c index 019f46c0690c..c2ad2ff32a15 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -83,38 +83,6 @@ struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string) return buf; } -static struct sk_buff *tipc_show_stats(void) -{ - struct sk_buff *buf; - struct tlv_desc *rep_tlv; - char *pb; - int pb_len; - int str_len; - u32 value; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) - return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - value = ntohl(*(u32 *)TLV_DATA(req_tlv_area)); - if (value != 0) - return tipc_cfg_reply_error_string("unsupported argument"); - - buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); - if (buf == NULL) - return NULL; - - rep_tlv = (struct tlv_desc *)buf->data; - pb = TLV_DATA(rep_tlv); - pb_len = ULTRA_STRING_MAX_LEN; - - str_len = tipc_snprintf(pb, pb_len, "TIPC version " TIPC_MOD_VER "\n"); - str_len += 1; /* for "\0" */ - skb_put(buf, TLV_SPACE(str_len)); - TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); - - return buf; -} - struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, const void *request_area, int request_space, int reply_headroom) @@ -142,9 +110,6 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, case TIPC_CMD_NOOP: rep_tlv_buf = tipc_cfg_reply_none(); break; - case TIPC_CMD_SHOW_STATS: - rep_tlv_buf = tipc_show_stats(); - break; case TIPC_CMD_NOT_NET_ADMIN: rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN); diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 415909054ec0..cb9086d259df 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -888,6 +888,18 @@ static int tipc_nl_compat_net_dump(struct tipc_nl_compat_msg *msg, return tipc_add_tlv(msg->rep, TIPC_TLV_UNSIGNED, &id, sizeof(id)); } +static int tipc_cmd_show_stats_compat(struct tipc_nl_compat_msg *msg) +{ + msg->rep = tipc_tlv_alloc(ULTRA_STRING_MAX_LEN); + if (!msg->rep) + return -ENOMEM; + + tipc_tlv_init(msg->rep, TIPC_TLV_ULTRA_STRING); + tipc_tlv_sprintf(msg->rep, "TIPC version " TIPC_MOD_VER "\n"); + + return 0; +} + static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) { struct tipc_nl_compat_cmd_dump dump; @@ -976,6 +988,8 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) dump.dumpit = tipc_nl_net_dump; dump.format = tipc_nl_compat_net_dump; return tipc_nl_compat_dumpit(&dump, msg); + case TIPC_CMD_SHOW_STATS: + return tipc_cmd_show_stats_compat(msg); } return -EOPNOTSUPP; @@ -1088,6 +1102,7 @@ static int tipc_nl_compat_tmp_wrap(struct sk_buff *skb, struct genl_info *info) case TIPC_CMD_SET_NODE_ADDR: case TIPC_CMD_SET_NETID: case TIPC_CMD_GET_NETID: + case TIPC_CMD_SHOW_STATS: return tipc_nl_compat_recv(skb, info); } From 22ae7cff509f3bb22caaa0003f67eeb93d338fed Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:18 +0100 Subject: [PATCH 16/17] tipc: nl compat add noop and remove legacy nl framework Add TIPC_CMD_NOOP to compat layer and remove the old framework. All legacy nl commands are now converted to the compat layer in netlink_compat.c. Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/Makefile | 2 +- net/tipc/bearer.c | 1 - net/tipc/config.c | 157 -------------------------------------- net/tipc/config.h | 67 ---------------- net/tipc/core.c | 3 +- net/tipc/link.c | 1 - net/tipc/log.c | 1 - net/tipc/name_table.c | 4 +- net/tipc/net.c | 2 - net/tipc/netlink_compat.c | 73 ++---------------- net/tipc/node.c | 2 +- net/tipc/socket.c | 1 - 12 files changed, 13 insertions(+), 301 deletions(-) delete mode 100644 net/tipc/config.c delete mode 100644 net/tipc/config.h diff --git a/net/tipc/Makefile b/net/tipc/Makefile index 69b82bbc60d3..6864b9de2404 100644 --- a/net/tipc/Makefile +++ b/net/tipc/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_TIPC) := tipc.o -tipc-y += addr.o bcast.o bearer.o config.o \ +tipc-y += addr.o bcast.o bearer.o \ core.o link.o discover.o msg.o \ name_distr.o subscr.o name_table.o net.o \ netlink.o netlink_compat.o node.o socket.o log.o eth_media.o \ diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index c7e3b5d3baa9..858c5a6c32df 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -36,7 +36,6 @@ #include #include "core.h" -#include "config.h" #include "bearer.h" #include "link.h" #include "discover.h" diff --git a/net/tipc/config.c b/net/tipc/config.c deleted file mode 100644 index c2ad2ff32a15..000000000000 --- a/net/tipc/config.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * net/tipc/config.c: TIPC configuration management code - * - * Copyright (c) 2002-2006, Ericsson AB - * Copyright (c) 2004-2007, 2010-2013, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "socket.h" -#include "name_table.h" -#include "config.h" -#include "server.h" - -#define REPLY_TRUNCATED "\n" - -static const void *req_tlv_area; /* request message TLV area */ -static int req_tlv_space; /* request message TLV area size */ -static int rep_headroom; /* reply message headroom to use */ - -struct sk_buff *tipc_cfg_reply_alloc(int payload_size) -{ - struct sk_buff *buf; - - buf = alloc_skb(rep_headroom + payload_size, GFP_ATOMIC); - if (buf) - skb_reserve(buf, rep_headroom); - return buf; -} - -int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type, - void *tlv_data, int tlv_data_size) -{ - struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(buf); - int new_tlv_space = TLV_SPACE(tlv_data_size); - - if (skb_tailroom(buf) < new_tlv_space) - return 0; - skb_put(buf, new_tlv_space); - tlv->tlv_type = htons(tlv_type); - tlv->tlv_len = htons(TLV_LENGTH(tlv_data_size)); - if (tlv_data_size && tlv_data) - memcpy(TLV_DATA(tlv), tlv_data, tlv_data_size); - return 1; -} - -struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string) -{ - struct sk_buff *buf; - int string_len = strlen(string) + 1; - - buf = tipc_cfg_reply_alloc(TLV_SPACE(string_len)); - if (buf) - tipc_cfg_append_tlv(buf, tlv_type, string, string_len); - return buf; -} - -struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, - const void *request_area, int request_space, - int reply_headroom) -{ - struct sk_buff *rep_tlv_buf; - - rtnl_lock(); - - /* Save request and reply details in a well-known location */ - req_tlv_area = request_area; - req_tlv_space = request_space; - rep_headroom = reply_headroom; - - /* Check command authorization */ - if (likely(in_own_node(net, orig_node))) { - /* command is permitted */ - } else { - rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (cannot be done remotely)"); - goto exit; - } - - /* Call appropriate processing routine */ - switch (cmd) { - case TIPC_CMD_NOOP: - rep_tlv_buf = tipc_cfg_reply_none(); - break; - case TIPC_CMD_NOT_NET_ADMIN: - rep_tlv_buf = - tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN); - break; - case TIPC_CMD_SET_MAX_ZONES: - case TIPC_CMD_GET_MAX_ZONES: - case TIPC_CMD_SET_MAX_SLAVES: - case TIPC_CMD_GET_MAX_SLAVES: - case TIPC_CMD_SET_MAX_CLUSTERS: - case TIPC_CMD_GET_MAX_CLUSTERS: - case TIPC_CMD_SET_MAX_NODES: - case TIPC_CMD_GET_MAX_NODES: - case TIPC_CMD_SET_MAX_SUBSCR: - case TIPC_CMD_GET_MAX_SUBSCR: - case TIPC_CMD_SET_MAX_PUBL: - case TIPC_CMD_GET_MAX_PUBL: - case TIPC_CMD_SET_LOG_SIZE: - case TIPC_CMD_SET_REMOTE_MNG: - case TIPC_CMD_GET_REMOTE_MNG: - case TIPC_CMD_DUMP_LOG: - case TIPC_CMD_SET_MAX_PORTS: - case TIPC_CMD_GET_MAX_PORTS: - rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (obsolete command)"); - break; - default: - rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (unknown command)"); - break; - } - - WARN_ON(rep_tlv_buf->len > TLV_SPACE(ULTRA_STRING_MAX_LEN)); - - /* Append an error message if we cannot return all requested data */ - if (rep_tlv_buf->len == TLV_SPACE(ULTRA_STRING_MAX_LEN)) { - if (*(rep_tlv_buf->data + ULTRA_STRING_MAX_LEN) != '\0') - sprintf(rep_tlv_buf->data + rep_tlv_buf->len - - sizeof(REPLY_TRUNCATED) - 1, REPLY_TRUNCATED); - } - - /* Return reply buffer */ -exit: - rtnl_unlock(); - return rep_tlv_buf; -} 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 @@ -/* - * net/tipc/config.h: Include file for TIPC configuration service code - * - * Copyright (c) 2003-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_CONFIG_H -#define _TIPC_CONFIG_H - -#include "link.h" - -#define ULTRA_STRING_MAX_LEN 32768 - -struct sk_buff *tipc_cfg_reply_alloc(int payload_size); -int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type, - void *tlv_data, int tlv_data_size); -struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string); - -static inline struct sk_buff *tipc_cfg_reply_none(void) -{ - return tipc_cfg_reply_alloc(0); -} - -static inline struct sk_buff *tipc_cfg_reply_error_string(char *string) -{ - return tipc_cfg_reply_string_type(TIPC_TLV_ERROR_STRING, string); -} - -static inline struct sk_buff *tipc_cfg_reply_ultra_string(char *string) -{ - return tipc_cfg_reply_string_type(TIPC_TLV_ULTRA_STRING, string); -} - -struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, - const void *req_tlv_area, int req_tlv_space, - int headroom); -#endif diff --git a/net/tipc/core.c b/net/tipc/core.c index 2d06d1f8b6e6..935205e6bcfe 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c @@ -39,7 +39,8 @@ #include "core.h" #include "name_table.h" #include "subscr.h" -#include "config.h" +#include "bearer.h" +#include "net.h" #include "socket.h" #include diff --git a/net/tipc/link.c b/net/tipc/link.c index dfe6f4d0b402..a4cf364316de 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -40,7 +40,6 @@ #include "socket.h" #include "name_distr.h" #include "discover.h" -#include "config.h" #include "netlink.h" #include diff --git a/net/tipc/log.c b/net/tipc/log.c index abef644f27d8..b186af06e361 100644 --- a/net/tipc/log.c +++ b/net/tipc/log.c @@ -35,7 +35,6 @@ */ #include "core.h" -#include "config.h" /** * tipc_snprintf - append formatted output to print buffer diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index c8eaa2afe875..105ba7adf06f 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -36,11 +36,13 @@ #include #include "core.h" -#include "config.h" +#include "netlink.h" #include "name_table.h" #include "name_distr.h" #include "subscr.h" #include "bcast.h" +#include "addr.h" +#include #define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */ diff --git a/net/tipc/net.c b/net/tipc/net.c index e4028f927c8a..a54f3cbe2246 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c @@ -40,8 +40,6 @@ #include "subscr.h" #include "socket.h" #include "node.h" -#include "config.h" -#include "bcast.h" static const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = { [TIPC_NLA_NET_UNSPEC] = { .type = NLA_UNSPEC }, diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index cb9086d259df..ce9121e8e990 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -32,7 +32,6 @@ */ #include "core.h" -#include "config.h" #include "bearer.h" #include "link.h" #include "name_table.h" @@ -909,6 +908,11 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) memset(&doit, 0, sizeof(doit)); switch (msg->cmd) { + case TIPC_CMD_NOOP: + msg->rep = tipc_tlv_alloc(0); + if (!msg->rep) + return -ENOMEM; + return 0; case TIPC_CMD_GET_BEARER_NAMES: msg->rep_size = MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME); dump.dumpit = tipc_nl_bearer_dump; @@ -1044,71 +1048,6 @@ send: return err; } -static int handle_cmd(struct sk_buff *skb, struct genl_info *info) -{ - struct net *net = genl_info_net(info); - struct sk_buff *rep_buf; - struct nlmsghdr *rep_nlh; - struct nlmsghdr *req_nlh = info->nlhdr; - struct tipc_genlmsghdr *req_userhdr = info->userhdr; - int hdr_space = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN); - u16 cmd; - - if ((req_userhdr->cmd & 0xC000) && - (!netlink_net_capable(skb, CAP_NET_ADMIN))) - cmd = TIPC_CMD_NOT_NET_ADMIN; - else - cmd = req_userhdr->cmd; - - rep_buf = tipc_cfg_do_cmd(net, req_userhdr->dest, cmd, - nlmsg_data(req_nlh) + GENL_HDRLEN + - TIPC_GENL_HDRLEN, - nlmsg_attrlen(req_nlh, GENL_HDRLEN + - TIPC_GENL_HDRLEN), hdr_space); - - if (rep_buf) { - skb_push(rep_buf, hdr_space); - rep_nlh = nlmsg_hdr(rep_buf); - memcpy(rep_nlh, req_nlh, hdr_space); - rep_nlh->nlmsg_len = rep_buf->len; - genlmsg_unicast(net, rep_buf, NETLINK_CB(skb).portid); - } - - return 0; -} - -/* Temporary function to keep functionality throughout the patchset - * without having to mess with the global variables and other trickery - * of the old API. - */ -static int tipc_nl_compat_tmp_wrap(struct sk_buff *skb, struct genl_info *info) -{ - struct tipc_genlmsghdr *req = info->userhdr; - - switch (req->cmd) { - case TIPC_CMD_GET_BEARER_NAMES: - case TIPC_CMD_ENABLE_BEARER: - case TIPC_CMD_DISABLE_BEARER: - case TIPC_CMD_SHOW_LINK_STATS: - case TIPC_CMD_GET_LINKS: - case TIPC_CMD_SET_LINK_TOL: - case TIPC_CMD_SET_LINK_PRI: - case TIPC_CMD_SET_LINK_WINDOW: - case TIPC_CMD_RESET_LINK_STATS: - case TIPC_CMD_SHOW_NAME_TABLE: - case TIPC_CMD_SHOW_PORTS: - case TIPC_CMD_GET_MEDIA_NAMES: - case TIPC_CMD_GET_NODES: - case TIPC_CMD_SET_NODE_ADDR: - case TIPC_CMD_SET_NETID: - case TIPC_CMD_GET_NETID: - case TIPC_CMD_SHOW_STATS: - return tipc_nl_compat_recv(skb, info); - } - - return handle_cmd(skb, info); -} - static struct genl_family tipc_genl_compat_family = { .id = GENL_ID_GENERATE, .name = TIPC_GENL_NAME, @@ -1121,7 +1060,7 @@ static struct genl_family tipc_genl_compat_family = { static struct genl_ops tipc_genl_compat_ops[] = { { .cmd = TIPC_GENL_CMD, - .doit = tipc_nl_compat_tmp_wrap, + .doit = tipc_nl_compat_recv, }, }; diff --git a/net/tipc/node.c b/net/tipc/node.c index ddaa2bbaa35d..86152de8248d 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -35,7 +35,7 @@ */ #include "core.h" -#include "config.h" +#include "link.h" #include "node.h" #include "name_distr.h" #include "socket.h" diff --git a/net/tipc/socket.c b/net/tipc/socket.c index e77d738bb771..f73e975af80b 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -40,7 +40,6 @@ #include "name_table.h" #include "node.h" #include "link.h" -#include "config.h" #include "name_distr.h" #include "socket.h" From 941787b82982b3f33ac398c8c00035ddd0f8c514 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:19 +0100 Subject: [PATCH 17/17] tipc: remove tipc_snprintf tipc_snprintf() was heavily utilized by the old netlink API which no longer exists (now netlink compat). In this patch we swap tipc_snprintf() to the identical scnprintf() in the only remaining occurrence. Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/Makefile | 2 +- net/tipc/bearer.c | 6 +++--- net/tipc/core.h | 2 -- net/tipc/log.c | 54 ----------------------------------------------- 4 files changed, 4 insertions(+), 60 deletions(-) delete mode 100644 net/tipc/log.c diff --git a/net/tipc/Makefile b/net/tipc/Makefile index 6864b9de2404..599b1a540d2b 100644 --- a/net/tipc/Makefile +++ b/net/tipc/Makefile @@ -7,7 +7,7 @@ obj-$(CONFIG_TIPC) := tipc.o tipc-y += addr.o bcast.o bearer.o \ core.o link.o discover.o msg.o \ name_distr.o subscr.o name_table.o net.o \ - netlink.o netlink_compat.o node.o socket.o log.o eth_media.o \ + netlink.o netlink_compat.o node.o socket.o eth_media.o \ server.o socket.o tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 858c5a6c32df..48852c2dcc03 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -111,13 +111,13 @@ void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a) m_ptr = media_find_id(a->media_id); if (m_ptr && !m_ptr->addr2str(a, addr_str, sizeof(addr_str))) - ret = tipc_snprintf(buf, len, "%s(%s)", m_ptr->name, addr_str); + ret = scnprintf(buf, len, "%s(%s)", m_ptr->name, addr_str); else { u32 i; - ret = tipc_snprintf(buf, len, "UNKNOWN(%u)", a->media_id); + ret = scnprintf(buf, len, "UNKNOWN(%u)", a->media_id); for (i = 0; i < sizeof(a->value); i++) - ret += tipc_snprintf(buf - ret, len + ret, + ret += scnprintf(buf - ret, len + ret, "-%02x", a->value[i]); } } diff --git a/net/tipc/core.h b/net/tipc/core.h index 451c346fd3cf..3dc68c7a966d 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h @@ -70,8 +70,6 @@ #define TIPC_MOD_VER "2.0.0" -int tipc_snprintf(char *buf, int len, const char *fmt, ...); - extern int tipc_net_id __read_mostly; extern int sysctl_tipc_rmem[3] __read_mostly; extern int sysctl_tipc_named_timeout __read_mostly; diff --git a/net/tipc/log.c b/net/tipc/log.c deleted file mode 100644 index b186af06e361..000000000000 --- a/net/tipc/log.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * net/tipc/log.c: TIPC print buffer routines for debugging - * - * Copyright (c) 1996-2006, Ericsson AB - * Copyright (c) 2005-2007, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" - -/** - * tipc_snprintf - append formatted output to print buffer - * @buf: pointer to print buffer - * @len: buffer length - * @fmt: formatted info to be printed - */ -int tipc_snprintf(char *buf, int len, const char *fmt, ...) -{ - int i; - va_list args; - - va_start(args, fmt); - i = vscnprintf(buf, len, fmt, args); - va_end(args); - return i; -}