Release 4.11 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"
#define INVALID_NODE_SIG 0x10000
/* 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 {
TIPC_NOTIFY_NODE_DOWN = (1 << 3),
TIPC_NOTIFY_NODE_UP = (1 << 4),
TIPC_NOTIFY_LINK_UP = (1 << 6),
TIPC_NOTIFY_LINK_DOWN = (1 << 7)
};
struct tipc_link_entry {
struct tipc_link *link;
spinlock_t lock; /* per link */
u32 mtu;
struct sk_buff_head inputq;
struct tipc_media_addr maddr;
};
struct tipc_bclink_entry {
struct tipc_link *link;
struct sk_buff_head inputq1;
struct sk_buff_head arrvq;
struct sk_buff_head inputq2;
struct sk_buff_head namedq;
};
/**
* struct tipc_node - TIPC node structure
* @addr: network address of node
* @ref: 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
* @inputq: pointer to input queue containing messages for msg event
* @namedq: pointer to name table input queue with name table messages
* @active_links: bearer ids of active links, used as index into links[] array
* @links: array containing references to all links to node
* @action_flags: bit mask of different types of node actions
* @state: connectivity state vs peer node
* @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
* @publ_list: list of publications
* @rcu: rcu struct for tipc_node
*/
struct tipc_node {
u32 addr;
struct kref kref;
rwlock_t lock;
struct net *net;
struct hlist_node hash;
int active_links[2];
struct tipc_link_entry links[MAX_BEARERS];
struct tipc_bclink_entry bc_entry;
int action_flags;
struct list_head list;
int state;
u16 sync_point;
int link_cnt;
u16 working_links;
u16 capabilities;
u32 signature;
u32 link_id;
struct list_head publ_list;
struct list_head conn_sks;
unsigned long keepalive_intv;
struct timer_list timer;
struct rcu_head rcu;
};
/* Node FSM states and events:
*/
enum {
SELF_DOWN_PEER_DOWN = 0xdd,
SELF_UP_PEER_UP = 0xaa,
SELF_DOWN_PEER_LEAVING = 0xd1,
SELF_UP_PEER_COMING = 0xac,
SELF_COMING_PEER_UP = 0xca,
SELF_LEAVING_PEER_DOWN = 0x1d,
NODE_FAILINGOVER = 0xf0,
NODE_SYNCHING = 0xcc
};
enum {
SELF_ESTABL_CONTACT_EVT = 0xece,
SELF_LOST_CONTACT_EVT = 0x1ce,
PEER_ESTABL_CONTACT_EVT = 0x9ece,
PEER_LOST_CONTACT_EVT = 0x91ce,
NODE_FAILOVER_BEGIN_EVT = 0xfbe,
NODE_FAILOVER_END_EVT = 0xfee,
NODE_SYNCH_BEGIN_EVT = 0xcbe,
NODE_SYNCH_END_EVT = 0xcee
};
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(unsigned long data);
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 void tipc_node_put(struct tipc_node *node);
static bool tipc_node_is_up(struct tipc_node *n);
struct tipc_sock_conn {
u32 port;
u32 peer_port;
u32 peer_node;
struct list_head list;
};
static struct tipc_link *node_active_link(struct tipc_node *n, int sel)
{
int bearer_id = n->active_links[sel & 1];
if (unlikely(bearer_id == INVALID_BEARER_ID))
return NULL;
return n->links[bearer_id].link;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jon Paul Maloy | 50 | 100.00% | 1 | 100.00% |
Total | 50 | 100.00% | 1 | 100.00% |
int tipc_node_get_mtu(struct net *net, u32 addr, u32 sel)
{
struct tipc_node *n;
int bearer_id;
unsigned int mtu = MAX_MSG_SIZE;
n = tipc_node_find(net, addr);
if (unlikely(!n))
return mtu;
bearer_id = n->active_links[sel & 1];
if (likely(bearer_id != INVALID_BEARER_ID))
mtu = n->links[bearer_id].mtu;
tipc_node_put(n);
return mtu;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jon Paul Maloy | 89 | 100.00% | 1 | 100.00% |
Total | 89 | 100.00% | 1 | 100.00% |
u16 tipc_node_get_capabilities(struct net *net, u32 addr)
{
struct tipc_node *n;
u16 caps;
n = tipc_node_find(net, addr);
if (unlikely(!n))
return TIPC_NODE_CAPABILITIES;
caps = n->capabilities;
tipc_node_put(n);
return caps;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jon Paul Maloy | 55 | 100.00% | 1 | 100.00% |
Total | 55 | 100.00% | 1 | 100.00% |
static void tipc_node_kref_release(struct kref *kref)
{
struct tipc_node *n = container_of(kref, struct tipc_node, kref);
kfree(n->bc_entry.link);
kfree_rcu(n, rcu);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ying Xue | 28 | 66.67% | 1 | 50.00% |
Jon Paul Maloy | 14 | 33.33% | 1 | 50.00% |
Total | 42 | 100.00% | 2 | 100.00% |
static void tipc_node_put(struct tipc_node *node)
{
kref_put(&node->kref, tipc_node_kref_release);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ying Xue | 20 | 95.24% | 1 | 50.00% |
Jon Paul Maloy | 1 | 4.76% | 1 | 50.00% |
Total | 21 | 100.00% | 2 | 100.00% |
static void tipc_node_get(struct tipc_node *node)
{
kref_get(&node->kref);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ying Xue | 19 | 100.00% | 1 | 100.00% |
Total | 19 | 100.00% | 1 | 100.00% |
/*
* tipc_node_find - locate specified node object, if it exists
*/
static struct tipc_node *tipc_node_find(struct net *net, u32 addr)
{
struct tipc_net *tn = tipc_net(net);
struct tipc_node *node;
unsigned int thash = tipc_hashfn(addr);
if (unlikely(!in_own_cluster_exact(net, addr)))
return NULL;
rcu_read_lock();
hlist_for_each_entry_rcu(node, &tn->node_htable[thash], hash) {
if (node->addr != addr)
continue;
if (!kref_get_unless_zero(&node->kref))
node = NULL;
break;
}
rcu_read_unlock();
return node;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Allan Stephens | 46 | 46.00% | 2 | 22.22% |
Jon Paul Maloy | 27 | 27.00% | 2 | 22.22% |
Ying Xue | 27 | 27.00% | 5 | 55.56% |
Total | 100 | 100.00% | 9 | 100.00% |
static void tipc_node_read_lock(struct tipc_node *n)
{
read_lock_bh(&n->lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jon Paul Maloy | 19 | 100.00% | 2 | 100.00% |
Total | 19 | 100.00% | 2 | 100.00% |
static void tipc_node_read_unlock(struct tipc_node *n)
{
read_unlock_bh(&n->lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jon Paul Maloy | 19 | 100.00% | 2 | 100.00% |
Total | 19 | 100.00% | 2 | 100.00% |
static void tipc_node_write_lock(struct tipc_node *n)
{
write_lock_bh(&n->lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jon Paul Maloy | 19 | 100.00% | 1 | 100.00% |
Total | 19 | 100.00% | 1 | 100.00% |
static void tipc_node_write_unlock_fast(struct tipc_node *n)
{
write_unlock_bh(&n->lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Parthasarathy Bhuvaragan | 19 | 100.00% | 1 | 100.00% |
Total | 19 | 100.00% | 1 | 100.00% |
static void tipc_node_write_unlock(struct tipc_node *n)
{
struct net *net = n->net;
u32 addr = 0;
u32 flags = n->action_flags;
u32 link_id = 0;
u32 bearer_id;
struct list_head *publ_list;
if (likely(!flags)) {
write_unlock_bh(&n->lock);
return;
}
addr = n->addr;
link_id = n->link_id;
bearer_id = link_id & 0xffff;
publ_list = &n->publ_list;
n->action_flags &= ~(TIPC_NOTIFY_NODE_DOWN | TIPC_NOTIFY_NODE_UP |
TIPC_NOTIFY_LINK_DOWN | TIPC_NOTIFY_LINK_UP);
write_unlock_bh(&n->lock);
if (flags & TIPC_NOTIFY_NODE_DOWN)
tipc_publ_notify(net, publ_list, addr);
if (flags & TIPC_NOTIFY_NODE_UP)
tipc_named_node_up(net, addr);
if (flags & TIPC_NOTIFY_LINK_UP) {
tipc_mon_peer_up(net, addr, bearer_id);
tipc_nametbl_publish(net, TIPC_LINK_STATE, addr, addr,
TIPC_NODE_SCOPE, link_id, addr);
}
if (flags & TIPC_NOTIFY_LINK_DOWN) {
tipc_mon_peer_down(net, addr, bearer_id);
tipc_nametbl_withdraw(net, TIPC_LINK_STATE, addr,
link_id, addr);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jon Paul Maloy | 204 | 100.00% | 2 | 100.00% |
Total | 204 | 100.00% | 2 | 100.00% |
struct tipc_node *tipc_node_create(struct net *net, u32 addr, u16 capabilities)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
struct tipc_node *n, *temp_node;
int i;
spin_lock_bh(&tn->node_list_lock);
n = tipc_node_find(net, addr);
if (n) {
/* Same node may come back with new capabilities */
n->capabilities = capabilities;
goto exit;
}
n = kzalloc(sizeof(*n), GFP_ATOMIC);
if (!n) {
pr_warn("Node creation failed, no memory\n");
goto exit;
}
n->addr = addr;
n->net = net;
n->capabilities = capabilities;
kref_init(&n->kref);
rwlock_init(&n->lock);
INIT_HLIST_NODE(&n->hash);
INIT_LIST_HEAD(&n->list);
INIT_LIST_HEAD(&n->publ_list);
INIT_LIST_HEAD(&n->conn_sks);
skb_queue_head_init(&n->bc_entry.namedq);
skb_queue_head_init(&n->bc_entry.inputq1);
__skb_queue_head_init(&n->bc_entry.arrvq);
skb_queue_head_init(&n->bc_entry.inputq2);
for (i = 0; i < MAX_BEARERS; i++)
spin_lock_init(&n->links[i].lock);
n->state = SELF_DOWN_PEER_LEAVING;
n->signature = INVALID_NODE_SIG;
n->active_links[0] = INVALID_BEARER_ID;
n->active_links[1] = INVALID_BEARER_ID;
if (!tipc_link_bc_create(net, tipc_own_addr(net), n->addr,
U16_MAX,
tipc_link_window(tipc_bc_sndlink(net)),
n->capabilities,
&n->bc_entry.inputq1,
&n->bc_entry.namedq,
tipc_bc_sndlink(net),
&n->bc_entry.link)) {
pr_warn("Broadcast rcv link creation failed, no memory\n");
kfree(n);
n = NULL;
goto exit;
}
tipc_node_get(n);
setup_timer(&n->timer, tipc_node_timeout, (unsigned long)n);
n->keepalive_intv = U32_MAX;
hlist_add_head_rcu(&n->hash, &tn->node_htable[tipc_hashfn(addr)]);
list_for_each_entry_rcu(temp_node, &tn->node_list, list) {
if (n->addr < temp_node->addr)
break;
}
list_add_tail_rcu(&n->list, &temp_node->list);
exit:
spin_unlock_bh(&tn->node_list_lock);
return n;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jon Paul Maloy | 296 | 68.36% | 15 | 46.88% |
Ying Xue | 47 | 10.85% | 5 | 15.62% |
Allan Stephens | 42 | 9.70% | 6 | 18.75% |
Per Liden | 41 | 9.47% | 2 | 6.25% |
Ingo Molnar | 3 | 0.69% | 1 | 3.12% |
David S. Miller | 2 | 0.46% | 1 | 3.12% |
Arnaldo Carvalho de Melo | 1 | 0.23% | 1 | 3.12% |
Erik Hugne | 1 | 0.23% | 1 | 3.12% |
Total | 433 | 100.00% | 32 | 100.00% |
static void tipc_node_calculate_timer(struct tipc_node *n, struct tipc_link *l)
{
unsigned long tol = tipc_link_tolerance(l);
unsigned long intv = ((tol / 4) > 500) ? 500 : tol / 4;
/* Link with lowest tolerance determines timer interval */
if (intv < n->keepalive_intv)
n->keepalive_intv = intv;
/* Ensure link's abort limit corresponds to current tolerance */
tipc_link_set_abort_limit(l, tol / n->keepalive_intv);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jon Paul Maloy | 72 | 100.00% | 3 | 100.00% |
Total | 72 | 100.00% | 3 | 100.00% |
static void tipc_node_delete(struct tipc_node *node)
{
list_del_rcu(&node->list);
hlist_del_rcu(&node->hash);
tipc_node_put(node);
del_timer_sync(&node->timer);
tipc_node_put(node);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jon Paul Maloy | 14 | 31.11% | 2 | 20.00% |
Allan Stephens | 12 | 26.67% | 2 | 20.00% |
Per Liden | 11 | 24.44% | 2 | 20.00% |
Ying Xue | 7 | 15.56% | 3 | 30.00% |
David S. Miller | 1 | 2.22% | 1 | 10.00% |
Total | 45 | 100.00% | 10 | 100.00% |
void tipc_node_stop(struct net *net)
{
struct tipc_net *tn = tipc_net(net);
struct tipc_node *node, *t_node;
spin_lock_bh(&tn->node_list_lock);
list_for_each_entry_safe(node, t_node, &tn->node_list, list)
tipc_node_delete(node);
spin_unlock_bh(&tn->node_list_lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ying Xue | 57 | 96.61% | 2 | 66.67% |
Jon Paul Maloy | 2 | 3.39% | 1 | 33.33% |
Total | 59 | 100.00% | 3 | 100.00% |
void tipc_node_subscribe(struct net *net, struct list_head *subscr, u32 addr)
{
struct tipc_node *n;
if (in_own_node(net, addr))
return;
n = tipc_node_find(net, addr);
if (!n) {
pr_warn("Node subscribe rejected, unknown node 0x%x\n", addr);
return;
}
tipc_node_write_lock(n);
list_add_tail(subscr, &n->publ_list);
tipc_node_write_unlock_fast(n);
tipc_node_put(n);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jon Paul Maloy | 81 | 98.78% | 2 | 66.67% |
Parthasarathy Bhuvaragan | 1 | 1.22% | 1 | 33.33% |
Total | 82 | 100.00% | 3 | 100.00% |
void tipc_node_unsubscribe(struct net *net, struct list_head *subscr, u32 addr)
{
struct tipc_node *n;
if (in_own_node(net, addr))
return;
n = tipc_node_find(net, addr);
if (!n) {
pr_warn("Node unsubscribe rejected, unknown node 0x%x\n", addr);
return;
}
tipc_node_write_lock(n);
list_del_init(subscr);
tipc_node_write_unlock_fast(n);
tipc_node_put(n);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jon Paul Maloy | 76 | 98.70% | 2 | 66.67% |
Parthasarathy Bhuvaragan | 1 | 1.30% | 1 | 33.33% |
Total | 77 | 100.00% | 3 | 100.00% |
int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port)
{
struct tipc_node *node;
struct tipc_sock_conn *conn;
int err = 0;
if (in_own_node(net, dnode))
return 0;
node = tipc_node_find(net, dnode);
if (!node) {
pr_warn("Connecting sock to node 0x%x failed\n", dnode);
return -EHOSTUNREACH;
}
conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
if (!conn) {
err = -EHOSTUNREACH;
goto exit;
}
conn->peer_node = dnode;
conn->port = port;
conn->peer_port = peer_port;
tipc_node_write_lock(node);
list_add_tail(&conn->list, &node->conn_sks);
tipc_node_write_unlock(node);
exit:
tipc_node_put(node);
return err;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jon Paul Maloy | 122 | 80.26% | 2 | 40.00% |
Ying Xue | 30 | 19.74% | 3 | 60.00% |
Total | 152 | 100.00% | 5 | 100.00% |
void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port)
{
struct tipc_node *node;
struct tipc_sock_conn *conn, *safe;
if (in_own_node(net, dnode))
return;
node = tipc_node_find(net, dnode);
if (!node)
return;
tipc_node_write_lock(node);
list_for_each_entry_safe(conn, safe, &node->conn_sks, list) {
if (port != conn->port)
continue;
list_del(&conn->list);
kfree(conn);
}
tipc_node_write_unlock(node);
tipc_node_put(node);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jon Paul Maloy | 89 | 86.41% | 2 | 40.00% |
Ying Xue | 14 | 13.59% | 3 | 60.00% |
Total | 103 | 100.00% | 5 | 100.00% |
/* tipc_node_timeout - handle expiration of node timer
*/
static void tipc_node_timeout(unsigned long data)
{
struct tipc_node *n = (struct tipc_node *)data;
struct tipc_link_entry *le;
struct sk_buff_head xmitq;
int bearer_id;
int rc = 0;
__skb_queue_head_init(&xmitq);
for (bearer_id = 0; bearer_id < MAX_BEARERS; bearer_id++) {
tipc_node_read_lock(n);
le = &n->links[bearer_id];
spin_lock_bh(&le->lock);
if (le->link) {
/* Link tolerance may change asynchronously: */
tipc_node_calculate_timer(n, le->link);
rc = tipc_link_timeout(le->link, &xmitq);
}
spin_unlock_bh(&le->lock);
tipc_node_read_unlock(n);
tipc_bearer_xmit(n->net, bearer_id, &xmitq, &le->maddr);
if (rc & TIPC_LINK_DOWN_EVT)
tipc_node_link_down(n, bearer_id, false);
}
mod_timer(&n->timer, jiffies + msecs_to_jiffies(n->keepalive_intv));
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jon Paul Maloy | 175 | 100.00% | 5 | 100.00% |
Total | 175 | 100.00% | 5 | 100.00% |
/**
* __tipc_node_link_up - handle addition of link
* 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)
{
int *slot0 = &n->active_links[0];
int *slot1 = &n->active_links[1];
struct tipc_link *ol = node_active_link(n, 0);
struct tipc_link *nl = n->links[bearer_id].link;
if (!nl || tipc_link_is_up(nl))
return;
tipc_link_fsm_evt(nl, LINK_ESTABLISH_EVT);
if (!tipc_link_is_up(nl))
return;
n->working_links++;
n->action_flags |= TIPC_NOTIFY_LINK_UP;
n->link_id = tipc_link_id(nl);
/* Leave room for tunnel header when returning 'mtu' to users: */
n->links[bearer_id].mtu = tipc_link_mtu(nl) - INT_H_SIZE;
tipc_bearer_add_dest(n->net, bearer_id, n->addr);
tipc_bcast_inc_bearer_dst_cnt(n->net, bearer_id);
pr_debug("Established link <%s> on network plane %c\n",
tipc_link_name(nl), tipc_link_plane(nl));
/* Ensure that a STATE message goes first */
tipc_link_build_state_msg(nl, xmitq);
/* First link? => give it both slots */
if (!ol) {
*slot0 = bearer_id;
*slot1 = bearer_id;
tipc_node_fsm_evt(n, SELF_ESTABL_CONTACT_EVT);
n->action_flags |= TIPC_NOTIFY_NODE_UP;
tipc_link_set_active(nl, true);
tipc_bcast_add_peer(n->net, nl, xmitq);
return;
}
/* Second link => redistribute slots */
if (tipc_link_prio(nl) > tipc_link_prio(ol)) {
pr_debug("Old link <%s> becomes standby\n", tipc_link_name(ol));
*slot0 = bearer_id;
*slot1 = bearer_id;
tipc_link_set_active(nl, true);
tipc_link_set_active(ol, false);
} else if (tipc_link_prio(nl) == tipc_link_prio(ol)) {
tipc_link_set_active(nl, true);
*slot1 = bearer_id;
} else {
pr_debug("New link <%s> is standby\n", tipc_link_name(nl));
}
/* Prepare synchronization with first link */
tipc_link_tnl_prepare(ol, nl, SYNCH_MSG, xmitq);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jon Paul Maloy | 255 | 77.51% | 16 | 69.57% |
Per Liden | 52 | 15.81% | 1 | 4.35% |
Ying Xue | 8 | 2.43% | 1 | 4.35% |
Allan Stephens | 7 | 2.13% | 2 | 8.70% |
Erik Hugne | 6 | 1.82% | 2 | 8.70% |
David S. Miller | 1 | 0.30% | 1 | 4.35% |
Total | 329 | 100.00% | 23 | 100.00% |
/**
* tipc_node_link_up - handle addition of link
*
* 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)
{
struct tipc_media_addr *maddr;
tipc_node_write_lock(n);
__tipc_node_link_up(n, bearer_id, xmitq);
maddr = &n->links[bearer_id].maddr;
tipc_bearer_xmit(n->net, bearer_id, xmitq, maddr);
tipc_node_write_unlock(n);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jon Paul Maloy | 61 | 89.71% | 6 | 75.00% |
Per Liden | 6 | 8.82% | 1 | 12.50% |
David S. Miller | 1 | 1.47% | 1 | 12.50% |
Total | 68 | 100.00% | 8 | 100.00% |
/**
* __tipc_node_link_down - handle loss of link
*/
static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id,
struct sk_buff_head *xmitq,
struct tipc_media_addr **maddr)
{
struct tipc_link_entry *le = &n->links[*bearer_id];
int *slot0 = &n->active_links[0];
int *slot1 = &n->active_links[1];
int i, highest = 0, prio;
struct tipc_link *l, *_l, *tnl;
l = n->links[*bearer_id].link;
if (!l || tipc_link_is_reset(l))
return;
n->working_links--;
n->action_flags |= TIPC_NOTIFY_LINK_DOWN;
n->link_id = tipc_link_id(l);
tipc_bearer_remove_dest(n->net, *bearer_id, n->addr);
pr_debug("Lost link <%s> on network plane %c\n",
tipc_link_name(l), tipc_link_plane(l));
/* Select new active link if any available */
*slot0 = INVALID_BEARER_ID;
*slot1 = INVALID_BEARER_ID;
for (i = 0; i < MAX_BEARERS; i++) {
_l = n->links[i].link;
if (!_l || !tipc_link_is_up(_l))
continue;
if (_l == l)
continue;
prio = tipc_link_prio(_l);
if (prio < highest)
continue;
if (prio > highest) {
highest = prio;
*slot0 = i;
*slot1 = i;
continue;
}
*slot1 = i;
}
if (!tipc_node_is_up(n)) {
if (tipc_link_peer_is_down