diff options
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r-- | net/tipc/node.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c index 2883f6a0ed98..f96dacf173ab 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -1257,6 +1257,19 @@ void tipc_node_broadcast(struct net *net, struct sk_buff *skb) | |||
1257 | kfree_skb(skb); | 1257 | kfree_skb(skb); |
1258 | } | 1258 | } |
1259 | 1259 | ||
1260 | static void tipc_node_mcast_rcv(struct tipc_node *n) | ||
1261 | { | ||
1262 | struct tipc_bclink_entry *be = &n->bc_entry; | ||
1263 | |||
1264 | /* 'arrvq' is under inputq2's lock protection */ | ||
1265 | spin_lock_bh(&be->inputq2.lock); | ||
1266 | spin_lock_bh(&be->inputq1.lock); | ||
1267 | skb_queue_splice_tail_init(&be->inputq1, &be->arrvq); | ||
1268 | spin_unlock_bh(&be->inputq1.lock); | ||
1269 | spin_unlock_bh(&be->inputq2.lock); | ||
1270 | tipc_sk_mcast_rcv(n->net, &be->arrvq, &be->inputq2); | ||
1271 | } | ||
1272 | |||
1260 | static void tipc_node_bc_sync_rcv(struct tipc_node *n, struct tipc_msg *hdr, | 1273 | static void tipc_node_bc_sync_rcv(struct tipc_node *n, struct tipc_msg *hdr, |
1261 | int bearer_id, struct sk_buff_head *xmitq) | 1274 | int bearer_id, struct sk_buff_head *xmitq) |
1262 | { | 1275 | { |
@@ -1330,15 +1343,8 @@ static void tipc_node_bc_rcv(struct net *net, struct sk_buff *skb, int bearer_id | |||
1330 | if (!skb_queue_empty(&xmitq)) | 1343 | if (!skb_queue_empty(&xmitq)) |
1331 | tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr); | 1344 | tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr); |
1332 | 1345 | ||
1333 | /* Deliver. 'arrvq' is under inputq2's lock protection */ | 1346 | if (!skb_queue_empty(&be->inputq1)) |
1334 | if (!skb_queue_empty(&be->inputq1)) { | 1347 | tipc_node_mcast_rcv(n); |
1335 | spin_lock_bh(&be->inputq2.lock); | ||
1336 | spin_lock_bh(&be->inputq1.lock); | ||
1337 | skb_queue_splice_tail_init(&be->inputq1, &be->arrvq); | ||
1338 | spin_unlock_bh(&be->inputq1.lock); | ||
1339 | spin_unlock_bh(&be->inputq2.lock); | ||
1340 | tipc_sk_mcast_rcv(net, &be->arrvq, &be->inputq2); | ||
1341 | } | ||
1342 | 1348 | ||
1343 | if (rc & TIPC_LINK_DOWN_EVT) { | 1349 | if (rc & TIPC_LINK_DOWN_EVT) { |
1344 | /* Reception reassembly failure => reset all links to peer */ | 1350 | /* Reception reassembly failure => reset all links to peer */ |
@@ -1565,6 +1571,9 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) | |||
1565 | if (unlikely(!skb_queue_empty(&n->bc_entry.namedq))) | 1571 | if (unlikely(!skb_queue_empty(&n->bc_entry.namedq))) |
1566 | tipc_named_rcv(net, &n->bc_entry.namedq); | 1572 | tipc_named_rcv(net, &n->bc_entry.namedq); |
1567 | 1573 | ||
1574 | if (unlikely(!skb_queue_empty(&n->bc_entry.inputq1))) | ||
1575 | tipc_node_mcast_rcv(n); | ||
1576 | |||
1568 | if (!skb_queue_empty(&le->inputq)) | 1577 | if (!skb_queue_empty(&le->inputq)) |
1569 | tipc_sk_rcv(net, &le->inputq); | 1578 | tipc_sk_rcv(net, &le->inputq); |
1570 | 1579 | ||