From e616071094c214a274fb66d0b297f8b25a1a34d7 Mon Sep 17 00:00:00 2001 From: Gerlando Falauto Date: Wed, 1 May 2013 12:04:44 +0000 Subject: tipc: cosmetic: clean up comments and break a long line Signed-off-by: Gerlando Falauto Signed-off-by: David S. Miller --- net/tipc/bcast.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'net/tipc') diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 25e159c2feb..0e2f4324f54 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -584,8 +584,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf, { int bp_index; - /* - * Prepare broadcast link message for reliable transmission, + /* Prepare broadcast link message for reliable transmission, * if first time trying to send it; * preparation is skipped for broadcast link protocol messages * since they are sent in an unreliable manner and don't need it @@ -613,11 +612,12 @@ static int tipc_bcbearer_send(struct sk_buff *buf, struct tipc_bearer *s = bcbearer->bpairs[bp_index].secondary; if (!p) - break; /* no more bearers to try */ + break; /* No more bearers to try */ - tipc_nmap_diff(&bcbearer->remains, &p->nodes, &bcbearer->remains_new); + tipc_nmap_diff(&bcbearer->remains, &p->nodes, + &bcbearer->remains_new); if (bcbearer->remains_new.count == bcbearer->remains.count) - continue; /* bearer pair doesn't add anything */ + continue; /* Nothing added by bearer pair */ if (!tipc_bearer_blocked(p)) tipc_bearer_send(p, buf, &p->bcast_addr); @@ -628,13 +628,14 @@ static int tipc_bcbearer_send(struct sk_buff *buf, /* unable to send on either bearer */ continue; + /* Swap bearers for next packet */ if (s) { bcbearer->bpairs[bp_index].primary = s; bcbearer->bpairs[bp_index].secondary = p; } if (bcbearer->remains_new.count == 0) - break; /* all targets reached */ + break; /* All targets reached */ bcbearer->remains = bcbearer->remains_new; } -- cgit v1.2.3-70-g09d2 From 77861d9c00900c0105b9d66ecf9fa612a43f8df5 Mon Sep 17 00:00:00 2001 From: Gerlando Falauto Date: Wed, 1 May 2013 12:04:45 +0000 Subject: tipc: tipc_bcbearer_send(): simplify bearer selection Signed-off-by: Gerlando Falauto Signed-off-by: David S. Miller --- net/tipc/bcast.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'net/tipc') diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 0e2f4324f54..d9d848d488e 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -610,23 +610,23 @@ static int tipc_bcbearer_send(struct sk_buff *buf, for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { struct tipc_bearer *p = bcbearer->bpairs[bp_index].primary; struct tipc_bearer *s = bcbearer->bpairs[bp_index].secondary; + struct tipc_bearer *b = p; if (!p) break; /* No more bearers to try */ - tipc_nmap_diff(&bcbearer->remains, &p->nodes, + if (tipc_bearer_blocked(p)) { + if (!s || tipc_bearer_blocked(s)) + continue; /* Can't use either bearer */ + b = s; + } + + tipc_nmap_diff(&bcbearer->remains, &b->nodes, &bcbearer->remains_new); if (bcbearer->remains_new.count == bcbearer->remains.count) continue; /* Nothing added by bearer pair */ - if (!tipc_bearer_blocked(p)) - tipc_bearer_send(p, buf, &p->bcast_addr); - else if (s && !tipc_bearer_blocked(s)) - /* unable to send on primary bearer */ - tipc_bearer_send(s, buf, &s->bcast_addr); - else - /* unable to send on either bearer */ - continue; + tipc_bearer_send(b, buf, &b->bcast_addr); /* Swap bearers for next packet */ if (s) { -- cgit v1.2.3-70-g09d2 From 488fc9af8267d0cd9036bc9db9f5dbbfde6de208 Mon Sep 17 00:00:00 2001 From: Gerlando Falauto Date: Wed, 1 May 2013 12:04:46 +0000 Subject: tipc: pskb_copy() buffers when sending on more than one bearer When sending packets, TIPC bearers use skb_clone() before writing their hardware header. This will however NOT copy the data buffer. So when the same packet is sent over multiple bearers (to reach multiple nodes), the same socket buffer data will be treated by multiple tipc_media drivers which will write their own hardware header through dev_hard_header(). Most of the time this is not a problem, because by the time the packet is processed by the second media, it has already been sent over the first one. However, when the first transmission is delayed (e.g. because of insufficient bandwidth or through a shaper), the next bearer will overwrite the hardware header, resulting in the packet being sent: a) with the wrong source address, when bearers of the same type, e.g. ethernet, are involved b) with a completely corrupt header, or even dropped, when bearers of different types are involved. So when the same socket buffer is to be sent multiple times, send a pskb_copy() instead (from the second instance on), and release it afterwards (the bearer will skb_clone() it anyway). Signed-off-by: Gerlando Falauto Signed-off-by: David S. Miller --- net/tipc/bcast.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'net/tipc') diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index d9d848d488e..e5f3da50782 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -611,6 +611,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf, struct tipc_bearer *p = bcbearer->bpairs[bp_index].primary; struct tipc_bearer *s = bcbearer->bpairs[bp_index].secondary; struct tipc_bearer *b = p; + struct sk_buff *tbuf; if (!p) break; /* No more bearers to try */ @@ -626,7 +627,17 @@ static int tipc_bcbearer_send(struct sk_buff *buf, if (bcbearer->remains_new.count == bcbearer->remains.count) continue; /* Nothing added by bearer pair */ - tipc_bearer_send(b, buf, &b->bcast_addr); + if (bp_index == 0) { + /* Use original buffer for first bearer */ + tipc_bearer_send(b, buf, &b->bcast_addr); + } else { + /* Avoid concurrent buffer access */ + tbuf = pskb_copy(buf, GFP_ATOMIC); + if (!tbuf) + break; + tipc_bearer_send(b, tbuf, &b->bcast_addr); + kfree_skb(tbuf); /* Bearer keeps a clone */ + } /* Swap bearers for next packet */ if (s) { -- cgit v1.2.3-70-g09d2