Commit 9dce285b authored by David S. Miller's avatar David S. Miller

Merge branch 'tipc-next'

Richard Alpe says:

====================
tipc: new compat layer for the legacy NL API

This is a compatibility / transcoding layer for the old netlink API.
It relies on the new netlink API to collect data or perform actions
(dumpit / doit).

The main benefit of this compat layer is that it removes a lot of
complex code from the tipc core as only the new API needs to be able
harness data or perform actions. I.e. the compat layer isn't concerned
with locking or how the internal data-structures look. As long as the
new API stays relatively intact the compat layer should be fine.

The main challenge in this compat layer is the randomness of the legacy
API. Some commands send binary data and some send ASCII data, some are
very picky in optimizing there buffer sizes and some just don't care.
Most legacy commands put there data in a single TLV (data container) but some
segment the data into multiple TLV's. This list of randomness goes on and on..
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c8ac18f2 941787b8
......@@ -272,6 +272,26 @@ 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 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;
......
......@@ -4,11 +4,11 @@
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 node.o socket.o log.o eth_media.o \
server.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
tipc-$(CONFIG_SYSCTL) += sysctl.o
......@@ -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;
......@@ -860,49 +860,6 @@ int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg)
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);
......
......@@ -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,
......
......@@ -36,7 +36,6 @@
#include <net/sock.h>
#include "core.h"
#include "config.h"
#include "bearer.h"
#include "link.h"
#include "discover.h"
......@@ -112,37 +111,17 @@ 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]);
}
}
/**
* 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
......@@ -205,35 +184,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);
......@@ -265,8 +215,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;
......@@ -422,22 +372,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;
......@@ -658,7 +592,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;
......@@ -785,7 +719,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;
......@@ -816,11 +750,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;
......@@ -924,7 +858,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;
......
......@@ -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
......@@ -199,13 +196,11 @@ 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,
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);
......
This diff is collapsed.
/*
* 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
......@@ -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 <linux/module.h>
......@@ -111,6 +112,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 +141,8 @@ static int __init tipc_init(void)
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 +153,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);
......
......@@ -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;
......@@ -115,5 +113,4 @@ void tipc_unregister_sysctl(void);
#define tipc_register_sysctl() 0
#define tipc_unregister_sysctl()
#endif
#endif
This diff is collapsed.
......@@ -215,14 +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_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);
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);
......
/*
* 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"
#include "config.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;
}
......@@ -36,11 +36,13 @@
#include <net/sock.h>
#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 <net/genetlink.h>
#define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */
......@@ -773,190 +775,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);
......@@ -1055,7 +873,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;
......
......@@ -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);
......
......@@ -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 },
......@@ -156,7 +154,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;
......@@ -208,7 +206,7 @@ int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb)
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;
......
......@@ -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 <net/genetlink.h>
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);
}
......@@ -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
This diff is collapsed.
......@@ -35,7 +35,7 @@
*/
#include "core.h"
#include "config.h"
#include "link.h"
#include "node.h"
#include "name_distr.h"
#include "socket.h"
......@@ -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)
......@@ -319,27 +316,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--;
}
}
......@@ -416,121 +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;
}
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
*
......@@ -623,7 +496,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;
......
......@@ -142,10 +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,
char *linkname, size_t len);
void tipc_node_unlock(struct tipc_node *node);
......
......@@ -40,7 +40,6 @@
#include "name_table.h"
#include "node.h"
#include "link.h"
#include "config.h"
#include "name_distr.h"
#include "socket.h"
......@@ -2281,91 +2280,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.
*/
......@@ -2783,7 +2697,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 +2778,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;
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment