d6418829ce
[ Upstream commit f73b12812a3d1d798b7517547ccdcf864844d2cd ]
Currently, TIPC transports intra-node user data messages directly
socket to socket, hence shortcutting all the lower layers of the
communication stack. This gives TIPC very good intra node performance,
both regarding throughput and latency.
We now introduce a similar mechanism for TIPC data traffic across
network namespaces located in the same kernel. On the send path, the
call chain is as always accompanied by the sending node's network name
space pointer. However, once we have reliably established that the
receiving node is represented by a namespace on the same host, we just
replace the namespace pointer with the receiving node/namespace's
ditto, and follow the regular socket receive patch though the receiving
node. This technique gives us a throughput similar to the node internal
throughput, several times larger than if we let the traffic go though
the full network stacks. As a comparison, max throughput for 64k
messages is four times larger than TCP throughput for the same type of
traffic.
To meet any security concerns, the following should be noted.
- All nodes joining a cluster are supposed to have been be certified
and authenticated by mechanisms outside TIPC. This is no different for
nodes/namespaces on the same host; they have to auto discover each
other using the attached interfaces, and establish links which are
supervised via the regular link monitoring mechanism. Hence, a kernel
local node has no other way to join a cluster than any other node, and
have to obey to policies set in the IP or device layers of the stack.
- Only when a sender has established with 100% certainty that the peer
node is located in a kernel local namespace does it choose to let user
data messages, and only those, take the crossover path to the receiving
node/namespace.
- If the receiving node/namespace is removed, its namespace pointer
is invalidated at all peer nodes, and their neighbor link monitoring
will eventually note that this node is gone.
- To ensure the "100% certainty" criteria, and prevent any possible
spoofing, received discovery messages must contain a proof that the
sender knows a common secret. We use the hash mix of the sending
node/namespace for this purpose, since it can be accessed directly by
all other namespaces in the kernel. Upon reception of a discovery
message, the receiver checks this proof against all the local
namespaces'hash_mix:es. If it finds a match, that, along with a
matching node id and cluster id, this is deemed sufficient proof that
the peer node in question is in a local namespace, and a wormhole can
be opened.
- We should also consider that TIPC is intended to be a cluster local
IPC mechanism (just like e.g. UNIX sockets) rather than a network
protocol, and hence we think it can justified to allow it to shortcut the
lower protocol layers.
Regarding traceability, we should notice that since commit 6c9081a391
("tipc: add loopback device tracking") it is possible to follow the node
internal packet flow by just activating tcpdump on the loopback
interface. This will be true even for this mechanism; by activating
tcpdump on the involved nodes' loopback interfaces their inter-name
space messaging can easily be tracked.
v2:
- update 'net' pointer when node left/rejoined
v3:
- grab read/write lock when using node ref obj
v4:
- clone traffics between netns to loopback
Suggested-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Hoang Le <hoang.h.le@dektech.com.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Stable-dep-of: c244c092f1ed ("tipc: fix unexpected link reset due to discovery messages")
Signed-off-by: Sasha Levin <sashal@kernel.org>
112 lines
5.0 KiB
C
112 lines
5.0 KiB
C
/*
|
|
* net/tipc/node.h: Include file for TIPC node management routines
|
|
*
|
|
* Copyright (c) 2000-2006, 2014-2016, Ericsson AB
|
|
* Copyright (c) 2005, 2010-2014, 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_NODE_H
|
|
#define _TIPC_NODE_H
|
|
|
|
#include "addr.h"
|
|
#include "net.h"
|
|
#include "bearer.h"
|
|
#include "msg.h"
|
|
|
|
/* Optional capabilities supported by this code version
|
|
*/
|
|
enum {
|
|
TIPC_SYN_BIT = (1),
|
|
TIPC_BCAST_SYNCH = (1 << 1),
|
|
TIPC_BCAST_STATE_NACK = (1 << 2),
|
|
TIPC_BLOCK_FLOWCTL = (1 << 3),
|
|
TIPC_BCAST_RCAST = (1 << 4),
|
|
TIPC_NODE_ID128 = (1 << 5),
|
|
TIPC_LINK_PROTO_SEQNO = (1 << 6),
|
|
TIPC_MCAST_RBCTL = (1 << 7),
|
|
TIPC_GAP_ACK_BLOCK = (1 << 8),
|
|
TIPC_TUNNEL_ENHANCED = (1 << 9)
|
|
};
|
|
|
|
#define TIPC_NODE_CAPABILITIES (TIPC_SYN_BIT | \
|
|
TIPC_BCAST_SYNCH | \
|
|
TIPC_BCAST_STATE_NACK | \
|
|
TIPC_BCAST_RCAST | \
|
|
TIPC_BLOCK_FLOWCTL | \
|
|
TIPC_NODE_ID128 | \
|
|
TIPC_LINK_PROTO_SEQNO | \
|
|
TIPC_MCAST_RBCTL | \
|
|
TIPC_GAP_ACK_BLOCK | \
|
|
TIPC_TUNNEL_ENHANCED)
|
|
#define INVALID_BEARER_ID -1
|
|
|
|
void tipc_node_stop(struct net *net);
|
|
bool tipc_node_get_id(struct net *net, u32 addr, u8 *id);
|
|
u32 tipc_node_get_addr(struct tipc_node *node);
|
|
u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr);
|
|
void tipc_node_check_dest(struct net *net, u32 onode, u8 *peer_id128,
|
|
struct tipc_bearer *bearer,
|
|
u16 capabilities, u32 signature, u32 hash_mixes,
|
|
struct tipc_media_addr *maddr,
|
|
bool *respond, bool *dupl_addr);
|
|
void tipc_node_delete_links(struct net *net, int bearer_id);
|
|
void tipc_node_apply_property(struct net *net, struct tipc_bearer *b, int prop);
|
|
int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 node,
|
|
char *linkname, size_t len);
|
|
int tipc_node_xmit(struct net *net, struct sk_buff_head *list, u32 dnode,
|
|
int selector);
|
|
int tipc_node_distr_xmit(struct net *net, struct sk_buff_head *list);
|
|
int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dest,
|
|
u32 selector);
|
|
void tipc_node_subscribe(struct net *net, struct list_head *subscr, u32 addr);
|
|
void tipc_node_unsubscribe(struct net *net, struct list_head *subscr, u32 addr);
|
|
void tipc_node_broadcast(struct net *net, struct sk_buff *skb);
|
|
int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port);
|
|
void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port);
|
|
int tipc_node_get_mtu(struct net *net, u32 addr, u32 sel, bool connected);
|
|
bool tipc_node_is_up(struct net *net, u32 addr);
|
|
u16 tipc_node_get_capabilities(struct net *net, u32 addr);
|
|
int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb);
|
|
int tipc_nl_node_dump_link(struct sk_buff *skb, struct netlink_callback *cb);
|
|
int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info);
|
|
int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info);
|
|
int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info);
|
|
int tipc_nl_peer_rm(struct sk_buff *skb, struct genl_info *info);
|
|
|
|
int tipc_nl_node_set_monitor(struct sk_buff *skb, struct genl_info *info);
|
|
int tipc_nl_node_get_monitor(struct sk_buff *skb, struct genl_info *info);
|
|
int tipc_nl_node_dump_monitor(struct sk_buff *skb, struct netlink_callback *cb);
|
|
int tipc_nl_node_dump_monitor_peer(struct sk_buff *skb,
|
|
struct netlink_callback *cb);
|
|
void tipc_node_pre_cleanup_net(struct net *exit_net);
|
|
#endif
|