Commit ce9a4f31 authored by David S. Miller's avatar David S. Miller

Merge branch 'tipc-fixes'

Jon Maloy says:

====================
tipc: three small fixes

Fixes for some broadcast link problems that may occur in large systems.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 34ee32c9 1fc07f3e
...@@ -330,6 +330,21 @@ static int tipc_reset_bearer(struct net *net, struct tipc_bearer *b) ...@@ -330,6 +330,21 @@ static int tipc_reset_bearer(struct net *net, struct tipc_bearer *b)
return 0; return 0;
} }
/* tipc_bearer_reset_all - reset all links on all bearers
*/
void tipc_bearer_reset_all(struct net *net)
{
struct tipc_net *tn = tipc_net(net);
struct tipc_bearer *b;
int i;
for (i = 0; i < MAX_BEARERS; i++) {
b = rcu_dereference_rtnl(tn->bearer_list[i]);
if (b)
tipc_reset_bearer(net, b);
}
}
/** /**
* bearer_disable * bearer_disable
* *
......
...@@ -198,6 +198,7 @@ void tipc_bearer_add_dest(struct net *net, u32 bearer_id, u32 dest); ...@@ -198,6 +198,7 @@ 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); 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); struct tipc_bearer *tipc_bearer_find(struct net *net, const char *name);
struct tipc_media *tipc_media_find(const char *name); struct tipc_media *tipc_media_find(const char *name);
void tipc_bearer_reset_all(struct net *net);
int tipc_bearer_setup(void); int tipc_bearer_setup(void);
void tipc_bearer_cleanup(void); void tipc_bearer_cleanup(void);
void tipc_bearer_stop(struct net *net); void tipc_bearer_stop(struct net *net);
......
...@@ -349,6 +349,8 @@ void tipc_link_remove_bc_peer(struct tipc_link *snd_l, ...@@ -349,6 +349,8 @@ void tipc_link_remove_bc_peer(struct tipc_link *snd_l,
u16 ack = snd_l->snd_nxt - 1; u16 ack = snd_l->snd_nxt - 1;
snd_l->ackers--; snd_l->ackers--;
rcv_l->bc_peer_is_up = true;
rcv_l->state = LINK_ESTABLISHED;
tipc_link_bc_ack_rcv(rcv_l, ack, xmitq); tipc_link_bc_ack_rcv(rcv_l, ack, xmitq);
tipc_link_reset(rcv_l); tipc_link_reset(rcv_l);
rcv_l->state = LINK_RESET; rcv_l->state = LINK_RESET;
...@@ -1559,7 +1561,12 @@ void tipc_link_bc_sync_rcv(struct tipc_link *l, struct tipc_msg *hdr, ...@@ -1559,7 +1561,12 @@ void tipc_link_bc_sync_rcv(struct tipc_link *l, struct tipc_msg *hdr,
if (!msg_peer_node_is_up(hdr)) if (!msg_peer_node_is_up(hdr))
return; return;
l->bc_peer_is_up = true; /* Open when peer ackowledges our bcast init msg (pkt #1) */
if (msg_ack(hdr))
l->bc_peer_is_up = true;
if (!l->bc_peer_is_up)
return;
/* Ignore if peers_snd_nxt goes beyond receive window */ /* Ignore if peers_snd_nxt goes beyond receive window */
if (more(peers_snd_nxt, l->rcv_nxt + l->window)) if (more(peers_snd_nxt, l->rcv_nxt + l->window))
......
...@@ -1297,10 +1297,6 @@ static void tipc_node_bc_rcv(struct net *net, struct sk_buff *skb, int bearer_id ...@@ -1297,10 +1297,6 @@ static void tipc_node_bc_rcv(struct net *net, struct sk_buff *skb, int bearer_id
rc = tipc_bcast_rcv(net, be->link, skb); rc = tipc_bcast_rcv(net, be->link, skb);
/* Broadcast link reset may happen at reassembly failure */
if (rc & TIPC_LINK_DOWN_EVT)
tipc_node_reset_links(n);
/* Broadcast ACKs are sent on a unicast link */ /* Broadcast ACKs are sent on a unicast link */
if (rc & TIPC_LINK_SND_BC_ACK) { if (rc & TIPC_LINK_SND_BC_ACK) {
tipc_node_read_lock(n); tipc_node_read_lock(n);
...@@ -1320,6 +1316,17 @@ static void tipc_node_bc_rcv(struct net *net, struct sk_buff *skb, int bearer_id ...@@ -1320,6 +1316,17 @@ static void tipc_node_bc_rcv(struct net *net, struct sk_buff *skb, int bearer_id
spin_unlock_bh(&be->inputq2.lock); spin_unlock_bh(&be->inputq2.lock);
tipc_sk_mcast_rcv(net, &be->arrvq, &be->inputq2); tipc_sk_mcast_rcv(net, &be->arrvq, &be->inputq2);
} }
if (rc & TIPC_LINK_DOWN_EVT) {
/* Reception reassembly failure => reset all links to peer */
if (!tipc_link_is_up(be->link))
tipc_node_reset_links(n);
/* Retransmission failure => reset all links to all peers */
if (!tipc_link_is_up(tipc_bc_sndlink(net)))
tipc_bearer_reset_all(net);
}
tipc_node_put(n); tipc_node_put(n);
} }
......
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