Commit 9d13ec65 authored by Jon Paul Maloy's avatar Jon Paul Maloy Committed by David S. Miller

tipc: introduce link entry structure to struct tipc_node

struct 'tipc_node' currently contains two arrays for link attributes,
one for the link pointers, and one for the usable link MTUs.

We now group those into a new struct 'tipc_link_entry', and intoduce
one single array consisting of such enties. Apart from being a cosmetic
improvement, this is a starting point for the strict master-slave
relation between node and link that we will introduce in the following
commits.
Reviewed-by: default avatarYing Xue <ying.xue@windriver.com>
Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6acc2326
...@@ -413,7 +413,7 @@ static void bclink_accept_pkt(struct tipc_node *node, u32 seqno) ...@@ -413,7 +413,7 @@ static void bclink_accept_pkt(struct tipc_node *node, u32 seqno)
* all nodes in the cluster don't ACK at the same time * all nodes in the cluster don't ACK at the same time
*/ */
if (((seqno - tn->own_addr) % TIPC_MIN_LINK_WIN) == 0) { if (((seqno - tn->own_addr) % TIPC_MIN_LINK_WIN) == 0) {
tipc_link_proto_xmit(node->active_links[node->addr & 1], tipc_link_proto_xmit(node_active_link(node, node->addr),
STATE_MSG, 0, 0, 0, 0); STATE_MSG, 0, 0, 0, 0);
tn->bcl->stats.sent_acks++; tn->bcl->stats.sent_acks++;
} }
......
...@@ -170,7 +170,7 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *buf, ...@@ -170,7 +170,7 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *buf,
return; return;
tipc_node_lock(node); tipc_node_lock(node);
node->capabilities = caps; node->capabilities = caps;
link = node->links[bearer->identity]; link = node->links[bearer->identity].link;
/* Prepare to validate requesting node's signature and media address */ /* Prepare to validate requesting node's signature and media address */
sign_match = (signature == node->signature); sign_match = (signature == node->signature);
......
...@@ -132,9 +132,11 @@ static void tipc_link_put(struct tipc_link *l_ptr) ...@@ -132,9 +132,11 @@ static void tipc_link_put(struct tipc_link *l_ptr)
static struct tipc_link *tipc_parallel_link(struct tipc_link *l) static struct tipc_link *tipc_parallel_link(struct tipc_link *l)
{ {
if (l->owner->active_links[0] != l) struct tipc_node *n = l->owner;
return l->owner->active_links[0];
return l->owner->active_links[1]; if (node_active_link(n, 0) != l)
return node_active_link(n, 0);
return node_active_link(n, 1);
} }
/* /*
...@@ -147,10 +149,11 @@ int tipc_link_is_up(struct tipc_link *l_ptr) ...@@ -147,10 +149,11 @@ int tipc_link_is_up(struct tipc_link *l_ptr)
return link_working_working(l_ptr) || link_working_unknown(l_ptr); return link_working_working(l_ptr) || link_working_unknown(l_ptr);
} }
int tipc_link_is_active(struct tipc_link *l_ptr) int tipc_link_is_active(struct tipc_link *l)
{ {
return (l_ptr->owner->active_links[0] == l_ptr) || struct tipc_node *n = l->owner;
(l_ptr->owner->active_links[1] == l_ptr);
return (node_active_link(n, 0) == l) || (node_active_link(n, 1) == l);
} }
/** /**
...@@ -240,7 +243,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr, ...@@ -240,7 +243,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
return NULL; return NULL;
} }
if (n_ptr->links[b_ptr->identity]) { if (n_ptr->links[b_ptr->identity].link) {
tipc_addr_string_fill(addr_string, n_ptr->addr); tipc_addr_string_fill(addr_string, n_ptr->addr);
pr_err("Attempt to establish second link on <%s> to %s\n", pr_err("Attempt to establish second link on <%s> to %s\n",
b_ptr->name, addr_string); b_ptr->name, addr_string);
...@@ -321,7 +324,7 @@ void tipc_link_delete_list(struct net *net, unsigned int bearer_id) ...@@ -321,7 +324,7 @@ void tipc_link_delete_list(struct net *net, unsigned int bearer_id)
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(node, &tn->node_list, list) { list_for_each_entry_rcu(node, &tn->node_list, list) {
tipc_node_lock(node); tipc_node_lock(node);
link = node->links[bearer_id]; link = node->links[bearer_id].link;
if (link) if (link)
tipc_link_delete(link); tipc_link_delete(link);
tipc_node_unlock(node); tipc_node_unlock(node);
...@@ -446,7 +449,7 @@ void tipc_link_reset(struct tipc_link *l_ptr) ...@@ -446,7 +449,7 @@ void tipc_link_reset(struct tipc_link *l_ptr)
if ((prev_state == RESET_UNKNOWN) || (prev_state == RESET_RESET)) if ((prev_state == RESET_UNKNOWN) || (prev_state == RESET_RESET))
return; return;
tipc_node_link_down(l_ptr->owner, l_ptr); tipc_node_link_down(l_ptr->owner, l_ptr->bearer_id);
tipc_bearer_remove_dest(owner->net, l_ptr->bearer_id, l_ptr->addr); tipc_bearer_remove_dest(owner->net, l_ptr->bearer_id, l_ptr->addr);
if (was_active_link && tipc_node_is_up(l_ptr->owner) && (pl != l_ptr)) { if (was_active_link && tipc_node_is_up(l_ptr->owner) && (pl != l_ptr)) {
...@@ -482,7 +485,7 @@ static void link_activate(struct tipc_link *link) ...@@ -482,7 +485,7 @@ static void link_activate(struct tipc_link *link)
link->rcv_nxt = 1; link->rcv_nxt = 1;
link->stats.recv_info = 1; link->stats.recv_info = 1;
link->silent_intv_cnt = 0; link->silent_intv_cnt = 0;
tipc_node_link_up(node, link); tipc_node_link_up(node, link->bearer_id);
tipc_bearer_add_dest(node->net, link->bearer_id, link->addr); tipc_bearer_add_dest(node->net, link->bearer_id, link->addr);
} }
...@@ -577,7 +580,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) ...@@ -577,7 +580,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
case TRAFFIC_MSG_EVT: case TRAFFIC_MSG_EVT:
break; break;
case ACTIVATE_MSG: case ACTIVATE_MSG:
other = l_ptr->owner->active_links[0]; other = node_active_link(l_ptr->owner, 0);
if (other && link_working_unknown(other)) if (other && link_working_unknown(other))
break; break;
l_ptr->state = WORKING_WORKING; l_ptr->state = WORKING_WORKING;
...@@ -606,7 +609,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) ...@@ -606,7 +609,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
switch (event) { switch (event) {
case TRAFFIC_MSG_EVT: case TRAFFIC_MSG_EVT:
case ACTIVATE_MSG: case ACTIVATE_MSG:
other = l_ptr->owner->active_links[0]; other = node_active_link(l_ptr->owner, 0);
if (other && link_working_unknown(other)) if (other && link_working_unknown(other))
break; break;
l_ptr->state = WORKING_WORKING; l_ptr->state = WORKING_WORKING;
...@@ -755,7 +758,7 @@ int tipc_link_xmit(struct net *net, struct sk_buff_head *list, u32 dnode, ...@@ -755,7 +758,7 @@ int tipc_link_xmit(struct net *net, struct sk_buff_head *list, u32 dnode,
node = tipc_node_find(net, dnode); node = tipc_node_find(net, dnode);
if (node) { if (node) {
tipc_node_lock(node); tipc_node_lock(node);
link = node->active_links[selector & 1]; link = node_active_link(node, selector & 1);
if (link) if (link)
rc = __tipc_link_xmit(net, link, list); rc = __tipc_link_xmit(net, link, list);
tipc_node_unlock(node); tipc_node_unlock(node);
...@@ -858,9 +861,9 @@ void tipc_link_reset_all(struct tipc_node *node) ...@@ -858,9 +861,9 @@ void tipc_link_reset_all(struct tipc_node *node)
tipc_addr_string_fill(addr_string, node->addr)); tipc_addr_string_fill(addr_string, node->addr));
for (i = 0; i < MAX_BEARERS; i++) { for (i = 0; i < MAX_BEARERS; i++) {
if (node->links[i]) { if (node->links[i].link) {
link_print(node->links[i], "Resetting link\n"); link_print(node->links[i].link, "Resetting link\n");
tipc_link_reset(node->links[i]); tipc_link_reset(node->links[i].link);
} }
} }
...@@ -1029,7 +1032,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr) ...@@ -1029,7 +1032,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
tipc_node_lock(n_ptr); tipc_node_lock(n_ptr);
/* Locate unicast link endpoint that should handle message */ /* Locate unicast link endpoint that should handle message */
l_ptr = n_ptr->links[b_ptr->identity]; l_ptr = n_ptr->links[b_ptr->identity].link;
if (unlikely(!l_ptr)) if (unlikely(!l_ptr))
goto unlock; goto unlock;
...@@ -1496,7 +1499,7 @@ static void tipc_link_tunnel_xmit(struct tipc_link *l_ptr, ...@@ -1496,7 +1499,7 @@ static void tipc_link_tunnel_xmit(struct tipc_link *l_ptr,
struct sk_buff *skb; struct sk_buff *skb;
u32 length = msg_size(msg); u32 length = msg_size(msg);
tunnel = l_ptr->owner->active_links[selector & 1]; tunnel = node_active_link(l_ptr->owner, selector & 1);
if (!tipc_link_is_up(tunnel)) { if (!tipc_link_is_up(tunnel)) {
pr_warn("%stunnel link no longer available\n", link_co_err); pr_warn("%stunnel link no longer available\n", link_co_err);
return; return;
...@@ -1522,7 +1525,7 @@ static void tipc_link_tunnel_xmit(struct tipc_link *l_ptr, ...@@ -1522,7 +1525,7 @@ static void tipc_link_tunnel_xmit(struct tipc_link *l_ptr,
void tipc_link_failover_send_queue(struct tipc_link *l_ptr) void tipc_link_failover_send_queue(struct tipc_link *l_ptr)
{ {
int msgcount; int msgcount;
struct tipc_link *tunnel = l_ptr->owner->active_links[0]; struct tipc_link *tunnel = node_active_link(l_ptr->owner, 0);
struct tipc_msg tunnel_hdr; struct tipc_msg tunnel_hdr;
struct sk_buff *skb; struct sk_buff *skb;
int split_bundles; int split_bundles;
...@@ -1556,8 +1559,8 @@ void tipc_link_failover_send_queue(struct tipc_link *l_ptr) ...@@ -1556,8 +1559,8 @@ void tipc_link_failover_send_queue(struct tipc_link *l_ptr)
return; return;
} }
split_bundles = (l_ptr->owner->active_links[0] != split_bundles = (node_active_link(l_ptr->owner, 0) !=
l_ptr->owner->active_links[1]); node_active_link(l_ptr->owner, 0));
skb_queue_walk(&l_ptr->transmq, skb) { skb_queue_walk(&l_ptr->transmq, skb) {
struct tipc_msg *msg = buf_msg(skb); struct tipc_msg *msg = buf_msg(skb);
...@@ -1660,7 +1663,7 @@ static bool tipc_link_failover_rcv(struct tipc_link *link, ...@@ -1660,7 +1663,7 @@ static bool tipc_link_failover_rcv(struct tipc_link *link,
if (bearer_id == link->bearer_id) if (bearer_id == link->bearer_id)
goto exit; goto exit;
pl = link->owner->links[bearer_id]; pl = link->owner->links[bearer_id].link;
if (pl && tipc_link_is_up(pl)) if (pl && tipc_link_is_up(pl))
tipc_link_reset(pl); tipc_link_reset(pl);
...@@ -1743,7 +1746,7 @@ static struct tipc_node *tipc_link_find_owner(struct net *net, ...@@ -1743,7 +1746,7 @@ static struct tipc_node *tipc_link_find_owner(struct net *net,
list_for_each_entry_rcu(n_ptr, &tn->node_list, list) { list_for_each_entry_rcu(n_ptr, &tn->node_list, list) {
tipc_node_lock(n_ptr); tipc_node_lock(n_ptr);
for (i = 0; i < MAX_BEARERS; i++) { for (i = 0; i < MAX_BEARERS; i++) {
l_ptr = n_ptr->links[i]; l_ptr = n_ptr->links[i].link;
if (l_ptr && !strcmp(l_ptr->name, link_name)) { if (l_ptr && !strcmp(l_ptr->name, link_name)) {
*bearer_id = i; *bearer_id = i;
found_node = n_ptr; found_node = n_ptr;
...@@ -1865,7 +1868,7 @@ int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info) ...@@ -1865,7 +1868,7 @@ int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info)
tipc_node_lock(node); tipc_node_lock(node);
link = node->links[bearer_id]; link = node->links[bearer_id].link;
if (!link) { if (!link) {
res = -EINVAL; res = -EINVAL;
goto out; goto out;
...@@ -2055,10 +2058,11 @@ static int __tipc_nl_add_node_links(struct net *net, struct tipc_nl_msg *msg, ...@@ -2055,10 +2058,11 @@ static int __tipc_nl_add_node_links(struct net *net, struct tipc_nl_msg *msg,
for (i = *prev_link; i < MAX_BEARERS; i++) { for (i = *prev_link; i < MAX_BEARERS; i++) {
*prev_link = i; *prev_link = i;
if (!node->links[i]) if (!node->links[i].link)
continue; continue;
err = __tipc_nl_add_link(net, msg, node->links[i], NLM_F_MULTI); err = __tipc_nl_add_link(net, msg,
node->links[i].link, NLM_F_MULTI);
if (err) if (err)
return err; return err;
} }
...@@ -2172,7 +2176,7 @@ int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info) ...@@ -2172,7 +2176,7 @@ int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info)
return -EINVAL; return -EINVAL;
tipc_node_lock(node); tipc_node_lock(node);
link = node->links[bearer_id]; link = node->links[bearer_id].link;
if (!link) { if (!link) {
tipc_node_unlock(node); tipc_node_unlock(node);
nlmsg_free(msg.skb); nlmsg_free(msg.skb);
...@@ -2227,7 +2231,7 @@ int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info) ...@@ -2227,7 +2231,7 @@ int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info)
tipc_node_lock(node); tipc_node_lock(node);
link = node->links[bearer_id]; link = node->links[bearer_id].link;
if (!link) { if (!link) {
tipc_node_unlock(node); tipc_node_unlock(node);
return -EINVAL; return -EINVAL;
......
...@@ -96,7 +96,7 @@ void named_cluster_distribute(struct net *net, struct sk_buff *skb) ...@@ -96,7 +96,7 @@ void named_cluster_distribute(struct net *net, struct sk_buff *skb)
dnode = node->addr; dnode = node->addr;
if (in_own_node(net, dnode)) if (in_own_node(net, dnode))
continue; continue;
if (!tipc_node_active_links(node)) if (!tipc_node_is_up(node))
continue; continue;
oskb = pskb_copy(skb, GFP_ATOMIC); oskb = pskb_copy(skb, GFP_ATOMIC);
if (!oskb) if (!oskb)
......
...@@ -224,126 +224,119 @@ void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port) ...@@ -224,126 +224,119 @@ void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port)
* *
* Link becomes active (alone or shared) or standby, depending on its priority. * Link becomes active (alone or shared) or standby, depending on its priority.
*/ */
void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr) void tipc_node_link_up(struct tipc_node *n, int bearer_id)
{ {
struct tipc_link **active = &n_ptr->active_links[0]; struct tipc_link_entry **actv = &n->active_links[0];
struct tipc_link_entry *le = &n->links[bearer_id];
struct tipc_link *l = le->link;
n_ptr->working_links++; /* Leave room for tunnel header when returning 'mtu' to users: */
n_ptr->action_flags |= TIPC_NOTIFY_LINK_UP; n->links[bearer_id].mtu = l->mtu - INT_H_SIZE;
n_ptr->link_id = l_ptr->peer_bearer_id << 16 | l_ptr->bearer_id;
n->working_links++;
n->action_flags |= TIPC_NOTIFY_LINK_UP;
n->link_id = l->peer_bearer_id << 16 | l->bearer_id;
pr_debug("Established link <%s> on network plane %c\n", pr_debug("Established link <%s> on network plane %c\n",
l_ptr->name, l_ptr->net_plane); l->name, l->net_plane);
if (!active[0]) { /* No active links ? => take both active slots */
active[0] = active[1] = l_ptr; if (!actv[0]) {
node_established_contact(n_ptr); actv[0] = le;
goto exit; actv[1] = le;
node_established_contact(n);
return;
} }
if (l_ptr->priority < active[0]->priority) { if (l->priority < actv[0]->link->priority) {
pr_debug("New link <%s> becomes standby\n", l_ptr->name); pr_debug("New link <%s> becomes standby\n", l->name);
goto exit; return;
} }
tipc_link_dup_queue_xmit(active[0], l_ptr); tipc_link_dup_queue_xmit(actv[0]->link, l);
if (l_ptr->priority == active[0]->priority) {
active[0] = l_ptr; /* Take one active slot if applicable */
goto exit; if (l->priority == actv[0]->link->priority) {
actv[0] = le;
return;
} }
pr_debug("Old link <%s> becomes standby\n", active[0]->name); /* Higher prio than current active? => take both active slots */
if (active[1] != active[0]) pr_debug("Old l <%s> becomes standby\n", actv[0]->link->name);
pr_debug("Old link <%s> becomes standby\n", active[1]->name); if (actv[1] != actv[0])
active[0] = active[1] = l_ptr; pr_debug("Old link <%s> now standby\n", actv[1]->link->name);
exit: actv[0] = le;
/* Leave room for changeover header when returning 'mtu' to users: */ actv[1] = le;
n_ptr->act_mtus[0] = active[0]->mtu - INT_H_SIZE;
n_ptr->act_mtus[1] = active[1]->mtu - INT_H_SIZE;
} }
/** /**
* node_select_active_links - select active link * node_select_active_links - select which working links should be active
*/ */
static void node_select_active_links(struct tipc_node *n_ptr) static void node_select_active_links(struct tipc_node *n)
{ {
struct tipc_link **active = &n_ptr->active_links[0]; struct tipc_link_entry **actv = &n->active_links[0];
u32 i; struct tipc_link *l;
u32 highest_prio = 0; u32 b, highest = 0;
active[0] = active[1] = NULL; actv[0] = NULL;
actv[1] = NULL;
for (i = 0; i < MAX_BEARERS; i++) {
struct tipc_link *l_ptr = n_ptr->links[i];
if (!l_ptr || !tipc_link_is_up(l_ptr) || for (b = 0; b < MAX_BEARERS; b++) {
(l_ptr->priority < highest_prio)) l = n->links[b].link;
if (!l || !tipc_link_is_up(l) || (l->priority < highest))
continue;
if (l->priority > highest) {
highest = l->priority;
actv[0] = &n->links[b];
actv[1] = &n->links[b];
continue; continue;
if (l_ptr->priority > highest_prio) {
highest_prio = l_ptr->priority;
active[0] = active[1] = l_ptr;
} else {
active[1] = l_ptr;
} }
actv[1] = &n->links[b];
} }
} }
/** /**
* tipc_node_link_down - handle loss of link * tipc_node_link_down - handle loss of link
*/ */
void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr) void tipc_node_link_down(struct tipc_node *n, int bearer_id)
{ {
struct tipc_net *tn = net_generic(n_ptr->net, tipc_net_id); struct tipc_link_entry **actv = &n->active_links[0];
struct tipc_link **active; struct tipc_link_entry *le = &n->links[bearer_id];
struct tipc_link *l = le->link;
n_ptr->working_links--; n->working_links--;
n_ptr->action_flags |= TIPC_NOTIFY_LINK_DOWN; n->action_flags |= TIPC_NOTIFY_LINK_DOWN;
n_ptr->link_id = l_ptr->peer_bearer_id << 16 | l_ptr->bearer_id; n->link_id = l->peer_bearer_id << 16 | l->bearer_id;
if (!tipc_link_is_active(l_ptr)) { if (!tipc_link_is_active(l)) {
pr_debug("Lost standby link <%s> on network plane %c\n", pr_debug("Lost standby link <%s> on network plane %c\n",
l_ptr->name, l_ptr->net_plane); l->name, l->net_plane);
return; return;
} }
pr_debug("Lost link <%s> on network plane %c\n", pr_debug("Lost link <%s> on network plane %c\n",
l_ptr->name, l_ptr->net_plane); l->name, l->net_plane);
active = &n_ptr->active_links[0];
if (active[0] == l_ptr)
active[0] = active[1];
if (active[1] == l_ptr)
active[1] = active[0];
if (active[0] == l_ptr)
node_select_active_links(n_ptr);
if (tipc_node_is_up(n_ptr))
tipc_link_failover_send_queue(l_ptr);
else
node_lost_contact(n_ptr);
/* Leave room for changeover header when returning 'mtu' to users: */ /* Resdistribute active slots if applicable */
if (active[0]) { if (actv[0] == le)
n_ptr->act_mtus[0] = active[0]->mtu - INT_H_SIZE; actv[0] = actv[1];
n_ptr->act_mtus[1] = active[1]->mtu - INT_H_SIZE; if (actv[1] == le)
return; actv[1] = actv[0];
}
/* Loopback link went down? No fragmentation needed from now on. */
if (n_ptr->addr == tn->own_addr) {
n_ptr->act_mtus[0] = MAX_MSG_SIZE;
n_ptr->act_mtus[1] = MAX_MSG_SIZE;
}
}
int tipc_node_active_links(struct tipc_node *n_ptr) /* Last link of this priority? => select other ones if available */
{ if (actv[0] == le)
return n_ptr->active_links[0] != NULL; node_select_active_links(n);
if (tipc_node_is_up(n))
tipc_link_failover_send_queue(l);
else
node_lost_contact(n);
} }
int tipc_node_is_up(struct tipc_node *n_ptr) bool tipc_node_is_up(struct tipc_node *n)
{ {
return tipc_node_active_links(n_ptr); return n->active_links[0];
} }
void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr) void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
{ {
n_ptr->links[l_ptr->bearer_id] = l_ptr; n_ptr->links[l_ptr->bearer_id].link = l_ptr;
n_ptr->link_cnt++; n_ptr->link_cnt++;
} }
...@@ -352,9 +345,9 @@ void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr) ...@@ -352,9 +345,9 @@ void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
int i; int i;
for (i = 0; i < MAX_BEARERS; i++) { for (i = 0; i < MAX_BEARERS; i++) {
if (l_ptr != n_ptr->links[i]) if (l_ptr != n_ptr->links[i].link)
continue; continue;
n_ptr->links[i] = NULL; n_ptr->links[i].link = NULL;
n_ptr->link_cnt--; n_ptr->link_cnt--;
} }
} }
...@@ -396,7 +389,7 @@ static void node_lost_contact(struct tipc_node *n_ptr) ...@@ -396,7 +389,7 @@ static void node_lost_contact(struct tipc_node *n_ptr)
/* Abort any ongoing link failover */ /* Abort any ongoing link failover */
for (i = 0; i < MAX_BEARERS; i++) { for (i = 0; i < MAX_BEARERS; i++) {
struct tipc_link *l_ptr = n_ptr->links[i]; struct tipc_link *l_ptr = n_ptr->links[i].link;
if (!l_ptr) if (!l_ptr)
continue; continue;
l_ptr->flags &= ~LINK_FAILINGOVER; l_ptr->flags &= ~LINK_FAILINGOVER;
...@@ -453,7 +446,7 @@ int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 addr, ...@@ -453,7 +446,7 @@ int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 addr,
goto exit; goto exit;
tipc_node_lock(node); tipc_node_lock(node);
link = node->links[bearer_id]; link = node->links[bearer_id].link;
if (link) { if (link) {
strncpy(linkname, link->name, len); strncpy(linkname, link->name, len);
err = 0; err = 0;
......
...@@ -89,6 +89,11 @@ struct tipc_node_bclink { ...@@ -89,6 +89,11 @@ struct tipc_node_bclink {
bool recv_permitted; bool recv_permitted;
}; };
struct tipc_link_entry {
struct tipc_link *link;
u32 mtu;
};
/** /**
* struct tipc_node - TIPC node structure * struct tipc_node - TIPC node structure
* @addr: network address of node * @addr: network address of node
...@@ -98,9 +103,8 @@ struct tipc_node_bclink { ...@@ -98,9 +103,8 @@ struct tipc_node_bclink {
* @hash: links to adjacent nodes in unsorted hash chain * @hash: links to adjacent nodes in unsorted hash chain
* @inputq: pointer to input queue containing messages for msg event * @inputq: pointer to input queue containing messages for msg event
* @namedq: pointer to name table input queue with name table messages * @namedq: pointer to name table input queue with name table messages
* @curr_link: the link holding the node lock, if any * @active_links: pointer into links[] array, identifying which links are active
* @active_links: pointers to active links to node * @links: array containing references to all links to node
* @links: pointers to all links to node
* @action_flags: bit mask of different types of node actions * @action_flags: bit mask of different types of node actions
* @bclink: broadcast-related info * @bclink: broadcast-related info
* @list: links to adjacent nodes in sorted list of cluster's nodes * @list: links to adjacent nodes in sorted list of cluster's nodes
...@@ -120,9 +124,8 @@ struct tipc_node { ...@@ -120,9 +124,8 @@ struct tipc_node {
struct hlist_node hash; struct hlist_node hash;
struct sk_buff_head *inputq; struct sk_buff_head *inputq;
struct sk_buff_head *namedq; struct sk_buff_head *namedq;
struct tipc_link *active_links[2]; struct tipc_link_entry *active_links[2];
u32 act_mtus[2]; struct tipc_link_entry links[MAX_BEARERS];
struct tipc_link *links[MAX_BEARERS];
int action_flags; int action_flags;
struct tipc_node_bclink bclink; struct tipc_node_bclink bclink;
struct list_head list; struct list_head list;
...@@ -142,10 +145,9 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr); ...@@ -142,10 +145,9 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr);
void tipc_node_stop(struct net *net); void tipc_node_stop(struct net *net);
void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr); void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr);
void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr); void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr);
void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr); void tipc_node_link_down(struct tipc_node *n_ptr, int bearer_id);
void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr); void tipc_node_link_up(struct tipc_node *n_ptr, int bearer_id);
int tipc_node_active_links(struct tipc_node *n_ptr); bool tipc_node_is_up(struct tipc_node *n);
int tipc_node_is_up(struct tipc_node *n_ptr);
int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 node, int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 node,
char *linkname, size_t len); char *linkname, size_t len);
void tipc_node_unlock(struct tipc_node *node); void tipc_node_unlock(struct tipc_node *node);
...@@ -165,20 +167,28 @@ static inline bool tipc_node_blocked(struct tipc_node *node) ...@@ -165,20 +167,28 @@ static inline bool tipc_node_blocked(struct tipc_node *node)
TIPC_NOTIFY_NODE_DOWN | TIPC_WAIT_OWN_LINKS_DOWN)); TIPC_NOTIFY_NODE_DOWN | TIPC_WAIT_OWN_LINKS_DOWN));
} }
static inline uint tipc_node_get_mtu(struct net *net, u32 addr, u32 selector) static inline struct tipc_link *node_active_link(struct tipc_node *n, int sel)
{ {
struct tipc_node *node; struct tipc_link_entry *le = n->active_links[sel & 1];
u32 mtu;
node = tipc_node_find(net, addr); if (likely(le))
return le->link;
return NULL;
}
if (likely(node)) { static inline uint tipc_node_get_mtu(struct net *net, u32 addr, u32 selector)
mtu = node->act_mtus[selector & 1]; {
tipc_node_put(node); struct tipc_node *n;
} else { struct tipc_link_entry *le;
mtu = MAX_MSG_SIZE; unsigned int mtu = MAX_MSG_SIZE;
}
n = tipc_node_find(net, addr);
if (unlikely(!n))
return mtu;
le = n->active_links[selector & 1];
if (likely(le))
mtu = le->mtu;
tipc_node_put(n);
return mtu; return mtu;
} }
......
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