aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/bcast.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/bcast.c')
-rw-r--r--net/tipc/bcast.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 2c4ecbe50082..00691b7c35f8 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -49,13 +49,19 @@
49#include "name_table.h" 49#include "name_table.h"
50#include "bcast.h" 50#include "bcast.h"
51 51
52
53#define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */ 52#define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */
54 53
55#define BCLINK_WIN_DEFAULT 20 /* bcast link window size (default) */ 54#define BCLINK_WIN_DEFAULT 20 /* bcast link window size (default) */
56 55
57#define BCLINK_LOG_BUF_SIZE 0 56#define BCLINK_LOG_BUF_SIZE 0
58 57
58/*
59 * Loss rate for incoming broadcast frames; used to test retransmission code.
60 * Set to N to cause every N'th frame to be discarded; 0 => don't discard any.
61 */
62
63#define TIPC_BCAST_LOSS_RATE 0
64
59/** 65/**
60 * struct bcbearer_pair - a pair of bearers used by broadcast link 66 * struct bcbearer_pair - a pair of bearers used by broadcast link
61 * @primary: pointer to primary bearer 67 * @primary: pointer to primary bearer
@@ -165,21 +171,18 @@ static int bclink_ack_allowed(u32 n)
165 * @after: sequence number of last packet to *not* retransmit 171 * @after: sequence number of last packet to *not* retransmit
166 * @to: sequence number of last packet to retransmit 172 * @to: sequence number of last packet to retransmit
167 * 173 *
168 * Called with 'node' locked, bc_lock unlocked 174 * Called with bc_lock locked
169 */ 175 */
170 176
171static void bclink_retransmit_pkt(u32 after, u32 to) 177static void bclink_retransmit_pkt(u32 after, u32 to)
172{ 178{
173 struct sk_buff *buf; 179 struct sk_buff *buf;
174 180
175 spin_lock_bh(&bc_lock);
176 buf = bcl->first_out; 181 buf = bcl->first_out;
177 while (buf && less_eq(buf_seqno(buf), after)) { 182 while (buf && less_eq(buf_seqno(buf), after)) {
178 buf = buf->next; 183 buf = buf->next;
179 } 184 }
180 if (buf != NULL) 185 tipc_link_retransmit(bcl, buf, mod(to - after));
181 tipc_link_retransmit(bcl, buf, mod(to - after));
182 spin_unlock_bh(&bc_lock);
183} 186}
184 187
185/** 188/**
@@ -399,7 +402,10 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
399 */ 402 */
400 403
401void tipc_bclink_recv_pkt(struct sk_buff *buf) 404void tipc_bclink_recv_pkt(struct sk_buff *buf)
402{ 405{
406#if (TIPC_BCAST_LOSS_RATE)
407 static int rx_count = 0;
408#endif
403 struct tipc_msg *msg = buf_msg(buf); 409 struct tipc_msg *msg = buf_msg(buf);
404 struct node* node = tipc_node_find(msg_prevnode(msg)); 410 struct node* node = tipc_node_find(msg_prevnode(msg));
405 u32 next_in; 411 u32 next_in;
@@ -420,9 +426,13 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
420 tipc_node_lock(node); 426 tipc_node_lock(node);
421 tipc_bclink_acknowledge(node, msg_bcast_ack(msg)); 427 tipc_bclink_acknowledge(node, msg_bcast_ack(msg));
422 tipc_node_unlock(node); 428 tipc_node_unlock(node);
429 spin_lock_bh(&bc_lock);
423 bcl->stats.recv_nacks++; 430 bcl->stats.recv_nacks++;
431 bcl->owner->next = node; /* remember requestor */
424 bclink_retransmit_pkt(msg_bcgap_after(msg), 432 bclink_retransmit_pkt(msg_bcgap_after(msg),
425 msg_bcgap_to(msg)); 433 msg_bcgap_to(msg));
434 bcl->owner->next = NULL;
435 spin_unlock_bh(&bc_lock);
426 } else { 436 } else {
427 tipc_bclink_peek_nack(msg_destnode(msg), 437 tipc_bclink_peek_nack(msg_destnode(msg),
428 msg_bcast_tag(msg), 438 msg_bcast_tag(msg),
@@ -433,6 +443,14 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
433 return; 443 return;
434 } 444 }
435 445
446#if (TIPC_BCAST_LOSS_RATE)
447 if (++rx_count == TIPC_BCAST_LOSS_RATE) {
448 rx_count = 0;
449 buf_discard(buf);
450 return;
451 }
452#endif
453
436 tipc_node_lock(node); 454 tipc_node_lock(node);
437receive: 455receive:
438 deferred = node->bclink.deferred_head; 456 deferred = node->bclink.deferred_head;