linux/net/tipc/node.c

/*
 * net/tipc/node.c: TIPC node management routines
 *
 * Copyright (c) 2000-2006, 2012-2016, Ericsson AB
 * Copyright (c) 2005-2006, 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.
 */

#include "core.h"
#include "link.h"
#include "node.h"
#include "name_distr.h"
#include "socket.h"
#include "bcast.h"
#include "monitor.h"
#include "discover.h"
#include "netlink.h"
#include "trace.h"
#include "crypto.h"

#define INVALID_NODE_SIG
#define NODE_CLEANUP_AFTER

/* Flags used to take different actions according to flag type
 * TIPC_NOTIFY_NODE_DOWN: notify node is down
 * TIPC_NOTIFY_NODE_UP: notify node is up
 * TIPC_DISTRIBUTE_NAME: publish or withdraw link state name type
 */
enum {};

struct tipc_link_entry {};

struct tipc_bclink_entry {};

/**
 * struct tipc_node - TIPC node structure
 * @addr: network address of node
 * @kref: reference counter to node object
 * @lock: rwlock governing access to structure
 * @net: the applicable net namespace
 * @hash: links to adjacent nodes in unsorted hash chain
 * @active_links: bearer ids of active links, used as index into links[] array
 * @links: array containing references to all links to node
 * @bc_entry: broadcast link entry
 * @action_flags: bit mask of different types of node actions
 * @state: connectivity state vs peer node
 * @preliminary: a preliminary node or not
 * @failover_sent: failover sent or not
 * @sync_point: sequence number where synch/failover is finished
 * @list: links to adjacent nodes in sorted list of cluster's nodes
 * @working_links: number of working links to node (both active and standby)
 * @link_cnt: number of links to node
 * @capabilities: bitmap, indicating peer node's functional capabilities
 * @signature: node instance identifier
 * @link_id: local and remote bearer ids of changing link, if any
 * @peer_id: 128-bit ID of peer
 * @peer_id_string: ID string of peer
 * @publ_list: list of publications
 * @conn_sks: list of connections (FIXME)
 * @timer: node's keepalive timer
 * @keepalive_intv: keepalive interval in milliseconds
 * @rcu: rcu struct for tipc_node
 * @delete_at: indicates the time for deleting a down node
 * @peer_net: peer's net namespace
 * @peer_hash_mix: hash for this peer (FIXME)
 * @crypto_rx: RX crypto handler
 */
struct tipc_node {};

/* Node FSM states and events:
 */
enum {};

enum {};

static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id,
				  struct sk_buff_head *xmitq,
				  struct tipc_media_addr **maddr);
static void tipc_node_link_down(struct tipc_node *n, int bearer_id,
				bool delete);
static void node_lost_contact(struct tipc_node *n, struct sk_buff_head *inputq);
static void tipc_node_delete(struct tipc_node *node);
static void tipc_node_timeout(struct timer_list *t);
static void tipc_node_fsm_evt(struct tipc_node *n, int evt);
static struct tipc_node *tipc_node_find(struct net *net, u32 addr);
static struct tipc_node *tipc_node_find_by_id(struct net *net, u8 *id);
static bool node_is_up(struct tipc_node *n);
static void tipc_node_delete_from_list(struct tipc_node *node);

struct tipc_sock_conn {};

static struct tipc_link *node_active_link(struct tipc_node *n, int sel)
{}

int tipc_node_get_mtu(struct net *net, u32 addr, u32 sel, bool connected)
{}

bool tipc_node_get_id(struct net *net, u32 addr, u8 *id)
{}

u16 tipc_node_get_capabilities(struct net *net, u32 addr)
{}

u32 tipc_node_get_addr(struct tipc_node *node)
{}

char *tipc_node_get_id_str(struct tipc_node *node)
{}

#ifdef CONFIG_TIPC_CRYPTO
/**
 * tipc_node_crypto_rx - Retrieve crypto RX handle from node
 * @__n: target tipc_node
 * Note: node ref counter must be held first!
 */
struct tipc_crypto *tipc_node_crypto_rx(struct tipc_node *__n)
{}

struct tipc_crypto *tipc_node_crypto_rx_by_list(struct list_head *pos)
{}

struct tipc_crypto *tipc_node_crypto_rx_by_addr(struct net *net, u32 addr)
{}
#endif

static void tipc_node_free(struct rcu_head *rp)
{}

static void tipc_node_kref_release(struct kref *kref)
{}

void tipc_node_put(struct tipc_node *node)
{}

void tipc_node_get(struct tipc_node *node)
{}

/*
 * tipc_node_find - locate specified node object, if it exists
 */
static struct tipc_node *tipc_node_find(struct net *net, u32 addr)
{}

/* tipc_node_find_by_id - locate specified node object by its 128-bit id
 * Note: this function is called only when a discovery request failed
 * to find the node by its 32-bit id, and is not time critical
 */
static struct tipc_node *tipc_node_find_by_id(struct net *net, u8 *id)
{}

static void tipc_node_read_lock(struct tipc_node *n)
	__acquires(n->lock)
{}

static void tipc_node_read_unlock(struct tipc_node *n)
	__releases(n->lock)
{}

static void tipc_node_write_lock(struct tipc_node *n)
	__acquires(n->lock)
{}

static void tipc_node_write_unlock_fast(struct tipc_node *n)
	__releases(n->lock)
{}

static void tipc_node_write_unlock(struct tipc_node *n)
	__releases(n->lock)
{}

static void tipc_node_assign_peer_net(struct tipc_node *n, u32 hash_mixes)
{}

struct tipc_node *tipc_node_create(struct net *net, u32 addr, u8 *peer_id,
				   u16 capabilities, u32 hash_mixes,
				   bool preliminary)
{}

static void tipc_node_calculate_timer(struct tipc_node *n, struct tipc_link *l)
{}

static void tipc_node_delete_from_list(struct tipc_node *node)
{}

static void tipc_node_delete(struct tipc_node *node)
{}

void tipc_node_stop(struct net *net)
{}

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)
{}

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)
{}

static void  tipc_node_clear_links(struct tipc_node *node)
{}

/* tipc_node_cleanup - delete nodes that does not
 * have active links for NODE_CLEANUP_AFTER time
 */
static bool tipc_node_cleanup(struct tipc_node *peer)
{}

/* tipc_node_timeout - handle expiration of node timer
 */
static void tipc_node_timeout(struct timer_list *t)
{}

/**
 * __tipc_node_link_up - handle addition of link
 * @n: target tipc_node
 * @bearer_id: id of the bearer
 * @xmitq: queue for messages to be xmited on
 * Node lock must be held by caller
 * Link becomes active (alone or shared) or standby, depending on its priority.
 */
static void __tipc_node_link_up(struct tipc_node *n, int bearer_id,
				struct sk_buff_head *xmitq)
{}

/**
 * tipc_node_link_up - handle addition of link
 * @n: target tipc_node
 * @bearer_id: id of the bearer
 * @xmitq: queue for messages to be xmited on
 *
 * Link becomes active (alone or shared) or standby, depending on its priority.
 */
static void tipc_node_link_up(struct tipc_node *n, int bearer_id,
			      struct sk_buff_head *xmitq)
{}

/**
 * tipc_node_link_failover() - start failover in case "half-failover"
 *
 * This function is only called in a very special situation where link
 * failover can be already started on peer node but not on this node.
 * This can happen when e.g.::
 *
 *	1. Both links <1A-2A>, <1B-2B> down
 *	2. Link endpoint 2A up, but 1A still down (e.g. due to network
 *	disturbance, wrong session, etc.)
 *	3. Link <1B-2B> up
 *	4. Link endpoint 2A down (e.g. due to link tolerance timeout)
 *	5. Node 2 starts failover onto link <1B-2B>
 *
 *	==> Node 1 does never start link/node failover!
 *
 * @n: tipc node structure
 * @l: link peer endpoint failingover (- can be NULL)
 * @tnl: tunnel link
 * @xmitq: queue for messages to be xmited on tnl link later
 */
static void tipc_node_link_failover(struct tipc_node *n, struct tipc_link *l,
				    struct tipc_link *tnl,
				    struct sk_buff_head *xmitq)
{}

/**
 * __tipc_node_link_down - handle loss of link
 * @n: target tipc_node
 * @bearer_id: id of the bearer
 * @xmitq: queue for messages to be xmited on
 * @maddr: output media address of the bearer
 */
static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id,
				  struct sk_buff_head *xmitq,
				  struct tipc_media_addr **maddr)
{}

static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete)
{}

static bool node_is_up(struct tipc_node *n)
{}

bool tipc_node_is_up(struct net *net, u32 addr)
{}

static u32 tipc_node_suggest_addr(struct net *net, u32 addr)
{}

/* tipc_node_try_addr(): Check if addr can be used by peer, suggest other if not
 * Returns suggested address if any, otherwise 0
 */
u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr)
{}

void tipc_node_check_dest(struct net *net, u32 addr,
			  u8 *peer_id, struct tipc_bearer *b,
			  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)
{}

static void tipc_node_reset_links(struct tipc_node *n)
{}

/* tipc_node_fsm_evt - node finite state machine
 * Determines when contact is allowed with peer node
 */
static void tipc_node_fsm_evt(struct tipc_node *n, int evt)
{}

static void node_lost_contact(struct tipc_node *n,
			      struct sk_buff_head *inputq)
{}

/**
 * tipc_node_get_linkname - get the name of a link
 *
 * @net: the applicable net namespace
 * @bearer_id: id of the bearer
 * @addr: peer node address
 * @linkname: link name output buffer
 * @len: size of @linkname output buffer
 *
 * Return: 0 on success
 */
int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 addr,
			   char *linkname, size_t len)
{}

/* Caller should hold node lock for the passed node */
static int __tipc_nl_add_node(struct tipc_nl_msg *msg, struct tipc_node *node)
{}

static void tipc_lxc_xmit(struct net *peer_net, struct sk_buff_head *list)
{}

/**
 * tipc_node_xmit() - general link level function for message sending
 * @net: the applicable net namespace
 * @list: chain of buffers containing message
 * @dnode: address of destination node
 * @selector: a number used for deterministic link selection
 * Consumes the buffer chain.
 * Return: 0 if success, otherwise: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE,-ENOBUF
 */
int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
		   u32 dnode, int selector)
{}

/* tipc_node_xmit_skb(): send single buffer to destination
 * Buffers sent via this function are generally TIPC_SYSTEM_IMPORTANCE
 * messages, which will not be rejected
 * The only exception is datagram messages rerouted after secondary
 * lookup, which are rare and safe to dispose of anyway.
 */
int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode,
		       u32 selector)
{}

/* tipc_node_distr_xmit(): send single buffer msgs to individual destinations
 * Note: this is only for SYSTEM_IMPORTANCE messages, which cannot be rejected
 */
int tipc_node_distr_xmit(struct net *net, struct sk_buff_head *xmitq)
{}

void tipc_node_broadcast(struct net *net, struct sk_buff *skb, int rc_dests)
{}

static void tipc_node_mcast_rcv(struct tipc_node *n)
{}

static void tipc_node_bc_sync_rcv(struct tipc_node *n, struct tipc_msg *hdr,
				  int bearer_id, struct sk_buff_head *xmitq)
{}

/**
 * tipc_node_bc_rcv - process TIPC broadcast packet arriving from off-node
 * @net: the applicable net namespace
 * @skb: TIPC packet
 * @bearer_id: id of bearer message arrived on
 *
 * Invoked with no locks held.
 */
static void tipc_node_bc_rcv(struct net *net, struct sk_buff *skb, int bearer_id)
{}

/**
 * tipc_node_check_state - check and if necessary update node state
 * @n: target tipc_node
 * @skb: TIPC packet
 * @bearer_id: identity of bearer delivering the packet
 * @xmitq: queue for messages to be xmited on
 * Return: true if state and msg are ok, otherwise false
 */
static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb,
				  int bearer_id, struct sk_buff_head *xmitq)
{}

/**
 * tipc_rcv - process TIPC packets/messages arriving from off-node
 * @net: the applicable net namespace
 * @skb: TIPC packet
 * @b: pointer to bearer message arrived on
 *
 * Invoked with no locks held. Bearer pointer must point to a valid bearer
 * structure (i.e. cannot be NULL), but bearer can be inactive.
 */
void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b)
{}

void tipc_node_apply_property(struct net *net, struct tipc_bearer *b,
			      int prop)
{}

int tipc_nl_peer_rm(struct sk_buff *skb, struct genl_info *info)
{}

int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb)
{}

/* tipc_node_find_by_name - locate owner node of link by link's name
 * @net: the applicable net namespace
 * @name: pointer to link name string
 * @bearer_id: pointer to index in 'node->links' array where the link was found.
 *
 * Returns pointer to node owning the link, or 0 if no matching link is found.
 */
static struct tipc_node *tipc_node_find_by_name(struct net *net,
						const char *link_name,
						unsigned int *bearer_id)
{}

int tipc_nl_node_set_link(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_reset_link_stats(struct sk_buff *skb, struct genl_info *info)
{}

/* Caller should hold node lock  */
static int __tipc_nl_add_node_links(struct net *net, struct tipc_nl_msg *msg,
				    struct tipc_node *node, u32 *prev_link,
				    bool bc_link)
{}

int tipc_nl_node_dump_link(struct sk_buff *skb, struct netlink_callback *cb)
{}

int tipc_nl_node_set_monitor(struct sk_buff *skb, struct genl_info *info)
{}

static int __tipc_nl_add_monitor_prop(struct net *net, struct tipc_nl_msg *msg)
{}

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)
{}

#ifdef CONFIG_TIPC_CRYPTO
static int tipc_nl_retrieve_key(struct nlattr **attrs,
				struct tipc_aead_key **pkey)
{}

static int tipc_nl_retrieve_nodeid(struct nlattr **attrs, u8 **node_id)
{}

static int tipc_nl_retrieve_rekeying(struct nlattr **attrs, u32 *intv)
{}

static int __tipc_nl_node_set_key(struct sk_buff *skb, struct genl_info *info)
{}

int tipc_nl_node_set_key(struct sk_buff *skb, struct genl_info *info)
{}

static int __tipc_nl_node_flush_key(struct sk_buff *skb,
				    struct genl_info *info)
{}

int tipc_nl_node_flush_key(struct sk_buff *skb, struct genl_info *info)
{}
#endif

/**
 * tipc_node_dump - dump TIPC node data
 * @n: tipc node to be dumped
 * @more: dump more?
 *        - false: dump only tipc node data
 *        - true: dump node link data as well
 * @buf: returned buffer of dump data in format
 */
int tipc_node_dump(struct tipc_node *n, bool more, char *buf)
{}

void tipc_node_pre_cleanup_net(struct net *exit_net)
{}